服務(wù)器端方法級權(quán)限控制
在服務(wù)器端我們可以通過Spring security提供的注解對方法來進(jìn)行權(quán)限控制笼恰。
Spring Security在方法的權(quán)限控制上支持三種類型的注解靴寂,JSR-250注解、@Secured注解和支持表達(dá)式的注解,這三種注解默認(rèn)都是沒有啟用的崎逃,需要單獨通過global-method-security元素的對應(yīng)屬性進(jìn)行啟用
JSR-250 注解
jsr-250注解有三個方法實現(xiàn)權(quán)限控制:@RolesAllowed、@PermitAll、@DenyAll
@RolesAllowed:表示具有定義的角色時才可以訪問對應(yīng)的方法
@PermitAll:允許所有角色進(jìn)行訪問缚柏,等于不進(jìn)行權(quán)限控制
@DenyAll:此方法跟@PermitAll正好相反,表示什么角色都不能進(jìn)行訪問
jsr-250主要是在Controller層中指定的方法上使用
1.在 springmvc.xml 配置文件中開啟
<!-- 開啟注解權(quán)限控制 -->
<security:global-method-security jsr250-annotations="enabled"></security:global-method-security>
2.在pom.xml文件中導(dǎo)入 jsr250 的依賴
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>jsr250-api</artifactId>
<version>1.0</version>
</dependency>
3.在指定的方法上添加注解@RolesAllowed
@RolesAllowed({"USER", "ADMIN"})
public String save(UserInfo userInfo){
userService.save(userInfo);
return "redirect:findAll";
}
該方法只要具有 "USER", "ADMIN" 任意一種權(quán)限就可以訪問碟贾。這里可以省略前綴 ROLE_ 币喧,實際的權(quán)限可能是 ROLE_ADMIN
ROLE_USER, ROLE_ADMIN 等權(quán)限需要在 spring-security.xml 配置中定義
<!-- 配置具體的規(guī)則
auto-config="true" 不用自己編寫登錄的頁面,框架提供默認(rèn)登錄頁面
use-expressions="false" 是否使用SPEL表達(dá)式 -->
<security:http auto-config="true" use-expressions="false">
<!-- 配置具體的攔截的規(guī)則 pattern="請求路徑的規(guī)則" access="訪問系統(tǒng)的人袱耽,必須有的權(quán)限" -->
<security:intercept-url pattern="/**" access="ROLE_USER,ROLE_ADMIN,ROLE_TEST,ROLE_PRODUCT,ROLE_ORDERS"/>
<!-- 定義跳轉(zhuǎn)的具體的頁面 -->
<security:form-login
login-page="/login.jsp"
login-processing-url="/login"
default-target-url="/index.jsp"
authentication-failure-url="/failer.jsp"
authentication-success-forward-url="/index.jsp"
/>
<!-- 關(guān)閉跨域請求 -->
<security:csrf disabled="true"/>
<!-- 退出 -->
<security:logout invalidate-session="true" logout-url="/logout" logout-success-url="/login.jsp"/>
</security:http>
如果沒有權(quán)限的用戶訪問時杀餐,會跳轉(zhuǎn)403錯誤頁面,體驗不太由友好朱巨,可以指定跳轉(zhuǎn)頁面史翘,需要在web.xml中配置如下信息。如果用戶訪問了沒有權(quán)限的請求地址,會跳轉(zhuǎn)到指定的 403.jsp 頁面
(此處有問題恶座,無法實現(xiàn)跳轉(zhuǎn)搀暑,暫時沒找到原因)
<error-page>
<error-code>403</error-code>
<location>/403.jsp</location>
</error-page>
@Secured 注解
1.在 springmvc.xml 配置文件中開啟
<!-- 開啟注解權(quán)限控制 -->
<security:global-method-security secured-annotations="enabled"></security:global-method-security>
2.在指定的方法上添加注解 @Secured 注解
@Secured("ROLE_ADMIN")
public String save(UserInfo userInfo){
userService.save(userInfo);
return "redirect:findAll";
}
該方法只要具有 "ROLE_USER", "ROLE_ADMIN" 任意一種權(quán)限就可以訪問。這里不可以省略前綴 ROLE_ 跨琳。
ROLE_USER, ROLE_ADMIN 等權(quán)限需要在 spring-security.xml 配置中定義(定義方式同 JSR-250 注解)
基于SPLE表達(dá)式的權(quán)限控制
1.在 springmvc.xml 配置文件中開啟
<!-- 開啟基于SPLE表達(dá)式的注解權(quán)限控制 -->
<security:global-method-security pre-post-annotations="enabled"></security:global-method-security>
2.在指定的方法上添加注解 @PreAuthorize 注解
@PreAuthorize("hasRole(['ROLE_ADMIN','ROLE_USER'])")
public String save(UserInfo userInfo){
userService.save(userInfo);
return "redirect:findAll";
}
該方法只要具有 "ROLE_USER", "ROLE_ADMIN" 任意一種權(quán)限就可以訪問自点。
@PreAuthorize("authentication.principal.userName=='admin'")
public String save(UserInfo userInfo){
userService.save(userInfo);
return "redirect:findAll";
}
該方法必須是用戶名為admin的用戶才可以訪問。
頁面端標(biāo)簽控制權(quán)限
在jsp頁面中我們可以使用spring security提供的權(quán)限標(biāo)簽來進(jìn)行權(quán)限控制
1.導(dǎo)入
1.1maven導(dǎo)入
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>version</version>
</dependency>
1.2頁面導(dǎo)入
<%@taglib uri="http://www.springframework.org/security/tags" prefix="security"%>
2.常用標(biāo)簽
2.1authentication:可以獲取當(dāng)前登錄的用戶的信息
property: 只允許指定Authentication所擁有的屬性脉让,可以進(jìn)行屬性的級聯(lián)獲取桂敛,如“principle.username”,
不允許直接通過方法進(jìn)行調(diào)用
htmlEscape:表示是否需要將html進(jìn)行轉(zhuǎn)義溅潜。默認(rèn)為true术唬。
scope:與var屬性一起使用,用于指定存放獲取的結(jié)果的屬性名的作用范圍滚澜,默認(rèn)我pageContext粗仓。Jsp中擁
有的作用范圍都進(jìn)行進(jìn)行指定
var: 用于指定一個屬性名,這樣當(dāng)獲取到了authentication的相關(guān)信息后會將其以var指定的屬性名進(jìn)行存
放设捐,默認(rèn)是存放在pageConext中
2.1.1獲取當(dāng)前登錄用戶的用戶名借浊,并且顯示在頁面
authentication 標(biāo)簽的 property 屬性
<security:authentication property="principal.username"></security:authentication>
2.2authorize:是用來判斷普通權(quán)限的,通過判斷用戶是否具有對應(yīng)的權(quán)限而控制其所包含內(nèi)容的顯示
access: 需要使用表達(dá)式來判斷權(quán)限萝招,當(dāng)表達(dá)式的返回結(jié)果為true時表示擁有對應(yīng)的權(quán)限
method:method屬性是配合url屬性一起使用的蚂斤,表示用戶應(yīng)當(dāng)具有指定url指定method訪問的權(quán)限,
method的默認(rèn)值為GET槐沼,可選值為http請求的7種方法
url:url表示如果用戶擁有訪問指定url的權(quán)限即表示可以顯示authorize標(biāo)簽包含的內(nèi)容
var:用于指定將權(quán)限鑒定的結(jié)果存放在pageContext的哪個屬性中
2.2.1在 spring-security.xml 配置文件開啟頁面支持SPEL表達(dá)式
開啟表達(dá)式:use-expressions="true"
開啟表達(dá)式后: access 也需要使用表達(dá)式
access="hasAnyRole('ROLE_USER','ROLE_ADMIN','ROLE_TEST','ROLE_PRODUCT','ROLE_ORDERS')"
<!--
配置具體的規(guī)則
auto-config="true" 不用自己編寫登錄的頁面曙蒸,框架提供默認(rèn)登錄頁面
use-expressions="false" 是否使用SPEL表達(dá)式
-->
<security:http auto-config="true" use-expressions="true">
<!-- 配置具體的攔截的規(guī)則 pattern="請求路徑的規(guī)則" access="訪問系統(tǒng)的人,必須有的角色" -->
<security:intercept-url pattern="/**"
access="hasAnyRole('ROLE_USER','ROLE_ADMIN','ROLE_TEST','ROLE_PRODUCT','ROLE_ORDERS')"/>
<!-- 定義跳轉(zhuǎn)的具體的頁面 -->
<security:form-login
login-page="/login.jsp"
login-processing-url="/login"
default-target-url="/index.jsp"
authentication-failure-url="/failer.jsp"
authentication-success-forward-url="/index.jsp"
/>
<!-- 關(guān)閉跨域請求 -->
<security:csrf disabled="true"/>
<!-- 退出 -->
<security:logout invalidate-session="true" logout-url="/logout" logout-success-url="/login.jsp"/>
</security:http>
如果不想在配置文件開啟表達(dá)式也可在配置文件添加如下 bean岗钩,配置后不開啟表達(dá)式也可以
<bean id="webexpressionHandler" class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler" />
2.2.2在頁面設(shè)置對應(yīng)權(quán)限可以顯示的內(nèi)容
authorize 標(biāo)簽中的 access 屬性
<security:authorize access="hasRole('ROLE_USER')">
<li id="system-setting">
<a href="${pageContext.request.contextPath}/user/findAll?page=1&size=5">
<i class="fa fa-circle-o"></i> 用戶管理
</a>
</li>
</security:authorize>
有 ROLE_USER 權(quán)限才可以顯示用戶管理