更新時間:2018年12月07日13時44分 來源:傳智播客 瀏覽次數(shù):
Spring Security方法級別的權(quán)限控制
引言
Spring Security是一個能夠為基于Spring的企業(yè)應(yīng)用系統(tǒng)提供安全訪問控制解決方案的安全框架,它利用Spring IOC、DI和AOP功能,為企業(yè)應(yīng)用系統(tǒng)提供聲明式的安全訪問控制功能,簡化企業(yè)系統(tǒng)為了安全控制而編寫大量重復(fù)代碼的工作,Spring Security支持Url級別的權(quán)限控制,同樣也支持方法級別的權(quán)限控制,今天主要介紹Spring Security方法級別的權(quán)限控制。
Spring Security方法級別權(quán)限控制方式
Spring Security方法級別權(quán)限控制主要有以下幾種方式:
• intercept-methods定義方法權(quán)限控制。
• 使用pointcut定義方法權(quán)限控制。
• 使用JSR-250注解定義方法權(quán)限控制。
• 使用@Secured注解定義方法權(quán)限控制。
• 注解使用表達式定義方法權(quán)限控制。
項目搭建
要想實現(xiàn)Spring Security方法級別的權(quán)限控制,必須先將項目搭建起來。
創(chuàng)建名稱為Spring-Security的web項目
在pom.xml文件中引入相關(guān)的依賴包。
org.springframework
spring-core
4.2.4.RELEASE
org.springframework
spring-web
4.2.4.RELEASE
org.springframework
spring-webmvc
4.2.4.RELEASE
org.springframework
spring-context-support
4.2.4.RELEASE
org.springframework.security
spring-security-web
4.1.0.RELEASE
org.springframework.security
spring-security-config
4.1.0.RELEASE
org.aspectj
aspectjweaver
1.8.7
org.lucee
jsr250
1.0.0
其中:
• spring-core、spring-web、spring-context-support是spring相關(guān)的依賴包。
• spring-webmvc是springmvc的依賴包。
• spring-security-web、spring-security-config是springsecurity相關(guān)的依賴包。
• aspectjweaver是aspectj的依賴包,用來實現(xiàn)pointcut方式的權(quán)限控制。
• jsr250是JSR-250標準的依賴包,用來實現(xiàn)jsr250注解方式的權(quán)限控制。
創(chuàng)建springmvc.xml和spring-security.xml配置文件。
創(chuàng)建springmvc.xml文件,用來掃描controller。
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
其中:
• context:component-scan是掃描controller注解配置。
• mvc:annotation-driven是開啟springmvc注解。
創(chuàng)建spring-security.xml文件,用來進行springsecurity權(quán)限控制。
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
authentication-failure-url="/login_error.html"/>
class="com.itheima.demo.user.UserDetailServiceImpl">
其中:
• http:用來設(shè)置Url權(quán)限過濾規(guī)則,其中的security屬性用來設(shè)置不受權(quán)限控制的行為,intercept-url用來設(shè)置訪問資源所需的權(quán)限,form-login用來設(shè)置權(quán)限不足跳轉(zhuǎn)的頁面,這是設(shè)置的是我們自己創(chuàng)建的頁面,csrf是關(guān)于csrf攻擊的設(shè)置。
• authentication-manager:設(shè)置認證管理器,authentication-provider是配置認證提供者,這里我們通過創(chuàng)建的UserDetailServiceImpl來進行實現(xiàn)。
配置web.xml文件
在web.xml文件中加載springmvc.xml文件和spring-security.xml文件,處理springmvc亂碼問題,設(shè)置springsecurity的攔截器。
contextConfigLocation
classpath:spring/spring-security.xml
org.springframework.web.context.ContextLoaderListener
springSecurityFilterChain
org.springframework.web.filter.DelegatingFilterProxy
springSecurityFilterChain
/ *
CharacterEncodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
utf-8
forceEncoding
true
CharacterEncodingFilter
/ *
springmvc
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:spring/springmvc.xml
springmvc
*.do
創(chuàng)建UserDetailServiceImpl
UserDetailServiceImpl用來進行權(quán)限認證,這里我們設(shè)置權(quán)限為ROLE_USER,會直接配置在spring-security.xml文件的authentication-provider中。
public class UserDetailServiceImpl implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
System.out.println("經(jīng)過認證類:"+username);
List authorities=new ArrayList();
authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
return new User(username,"123456",authorities);
}
}
創(chuàng)建UserController、UserService接口和UserServiceImpl接口實現(xiàn)類
創(chuàng)建UserController,調(diào)用Service中的操作
@RestController
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/findAll")
public void findAll(){
userService.findAll();
}
@RequestMapping("/find")
public void find(){
userService.find();
}
@RequestMapping("/add")
public void add(){
userService.add();
}
}
創(chuàng)建UserService接口
public interface UserService {
public void findAll();
public void find();
public void add();
}
創(chuàng)建UserServiceImpl實現(xiàn)UserService接口,實現(xiàn)具體的操作
public class UserServiceImpl implements UserService {
@Override
public void findAll() {
for (int i = 0; i < 5; i++) {
System.out.println("商品"+i);
}
}
@Override
public void find() {
System.out.println("商品");
}
@Override
public void add() {
System.out.println("添加商品");
}
}
配置權(quán)限控制所需的index.html、login.html頁面
index.html
登錄成功
login.html
運行測試
啟動項目
瀏覽器輸入地址"http://localhost:8082/index.html"會出現(xiàn)如下效果
: 說明權(quán)限控制已經(jīng)開始起作用了,接下來就可以進行方法級別的權(quán)限控制了。
SpringSecurity方法級別權(quán)限控制
intercept-methods方式權(quán)限控制
在spring-security.xml文件中配置:
其中:
• intercept-methods:需要定義在bean元素下,定義對當(dāng)前的bean的某些方法進行權(quán)限控制。
• protect:配置訪問方法所需的權(quán)限,需要指定兩個屬性,access和method,method表示需要攔截的方法名稱,可以使用通配符,access表示執(zhí)行對應(yīng)的方法需要擁有的權(quán)限,多個權(quán)限之間可以使用逗號分隔。
運行測試
運行測試,當(dāng)?shù)卿洺晒χ螅?/span>
在瀏覽器輸入"http://localhost:8082/find.do",在開發(fā)工具的打印臺會打印出
如下結(jié)果: 在瀏覽器輸入"http://localhost:8082/findAll.do",在開發(fā)工具的打印臺會打印出如下結(jié)果
: 在瀏覽器輸入"http://localhost:8082/add.do",會發(fā)現(xiàn)如下結(jié)果: 根據(jù)結(jié)果會發(fā)現(xiàn)當(dāng)通過find.do或者是findAll.do進行請求時,因為在spring-security.xml文件配置了訪問find*方法的訪問權(quán)限是ROLEUSER,所以會直接通過controller調(diào)用service的方法來完成請求,但是當(dāng)通過add.do進行請求時,因為在spring-security.xml文件配置了add方法的訪問權(quán)限是ROLEADMIN,權(quán)限不對,所以會提示訪問拒絕。
pointcut方式權(quán)限控制
使用pointcut方式進行權(quán)限控制,需要先引入aspectjweaver依賴包,同時需要在spring-security.xml文件中配置:
class="com.itheima.demo.service.UserServiceImpl" />
expression="execution(* com.itheima.demo.service.UserServiceImpl.find*())"
access="ROLE_USER"/>
expression="execution(* com.itheima.demo.service.UserServiceImpl.add(..))"
access="ROLE_ADMIN"/>
其中:
• 基于pointcut的方法權(quán)限控制是通過global-method-security下的protect-pointcut來定義的。
• protect-pointcut:protect-pointcut中有兩個屬性,expression和access,可以通過expression設(shè)置切點表達式來進行設(shè)置攔截的方法,通過access設(shè)置訪問權(quán)限。
運行測試
運行測試,當(dāng)?shù)卿洺晒χ螅?/span>
在瀏覽器輸入"http://localhost:8082/find.do",在開發(fā)工具的打印臺會打印出如下結(jié)果: 在瀏覽器輸入"http://localhost:8082/findAll.do",在開發(fā)工具的打印臺會打印出如下結(jié)果: 在瀏覽器輸入"http://localhost:8082/add.do",會發(fā)現(xiàn)如下結(jié)果: 根據(jù)結(jié)果會發(fā)現(xiàn)當(dāng)通過find.do或者是findAll.do進行請求時,因為在spring-security.xml中的protect-pointcut中配置了訪問find*方法的訪問權(quán)限是ROLEUSER,所以會直接通過controller調(diào)用service的方法來完成請求,但是當(dāng)通過add.do進行請求時,因為在spring-security.xml中的protect-pointcut配置了add方法的訪問權(quán)限是ROLEADMIN,權(quán)限不對,所以會提示訪問拒絕。
使用JSR-250注解方式權(quán)限控制
要使用JSR-250注解,首先需要引入jsr250依賴包,同時需要通過設(shè)置global-method-security元素的jsr250-annotation="enabled"來啟用基于JSR-250注解的支持,默認為disabled,具體配置如下:
另外還需要在對應(yīng)的java類中進行注解配置:
public class UserServiceImpl1 implements UserService {
@RolesAllowed("ROLE_USER")
@Override
public void findAll() {
for (int i = 0; i < 5; i++) {
System.out.println("商品"+i);
}
}
@DenyAll
@Override
public void find() {
System.out.println("商品");
}
@RolesAllowed("ROLE_ADMIN")
@Override
public void add() {
System.out.println("添加商品");
}
}
其中:
• @RolesAllowed:設(shè)置訪問對應(yīng)方法時所應(yīng)該具有的角色。
• @DenyAll: 表示無論什么角色都不能訪問。
運行測試
運行測試,當(dāng)?shù)卿洺晒χ螅?/span>
在瀏覽器輸入"http://localhost:8082/find.do",會發(fā)現(xiàn)如下結(jié)果: 在瀏覽器輸入"http://localhost:8082/findAll.do",在開發(fā)工具的打印臺會打印出如下結(jié)果
: 在瀏覽器輸入"http://localhost:8082/add.do",會發(fā)現(xiàn)如下結(jié)果: 根據(jù)結(jié)果會發(fā)現(xiàn)當(dāng)通過findAll.do進行請求時,因為配置了注解 @RolesAllowed("ROLEUSER"),所以會直接通過controller調(diào)用service的方法來完成請求,但是通過find.do進行請求時,因為配置了@DenyAll不允許任何人訪問,所以會提示訪問拒絕,當(dāng)通過add.do進行請求時,因為配置了@RolesAllowed("ROLEADMIN"),權(quán)限不對,所以會提示訪問拒絕。
使用@Secured注解方式權(quán)限控制
@Secured是由Spring Security定義的用來支持方法權(quán)限控制的注解。它的使用也是需要啟用對應(yīng)的支持才會生效的。通過設(shè)置global-method-security元素的secured-annotations="enabled"可以啟用,具體配置如下:
另外還需要在對應(yīng)的java類中進行注解配置:
public class UserServiceImpl implements UserService {
@Secured("ROLE_USER")
@Override
public void findAll() {
for (int i = 0; i < 5; i++) {
System.out.println("商品"+i);
}
}
@Secured("ROLE_USER")
@Override
public void find() {
System.out.println("商品");
}
@Secured("ROLE_ADMIN")
@Override
public void add() {
System.out.println("添加商品");
}
}
其中:
• @Secured:設(shè)置訪問對應(yīng)方法時所應(yīng)該具有的角色。
運行測試
運行測試,當(dāng)?shù)卿洺晒χ螅?/span>
在瀏覽器輸入"http://localhost:8082/find.do",在開發(fā)工具的打印臺會打印出如下結(jié)果: 在瀏覽器輸入"http://localhost:8082/findAll.do",在開發(fā)工具的打印臺會打印出如下結(jié)果: 在瀏覽器輸入"http://localhost:8082/add.do",會發(fā)現(xiàn)如下結(jié)果:
根據(jù)結(jié)果會發(fā)現(xiàn)當(dāng)通過find.do或者是findAll.do進行請求時,因為配置了注解@Secured("ROLEUSER"),所以會直接通過controller調(diào)用service的方法來完成請求,但是當(dāng)通過add.do進行請求時,因為配置的注解是@Secured("ROLEADMIN"),權(quán)限不對,所以會提示訪問拒絕。
注解使用表達式方式權(quán)限控制
Spring Security中也可以使用表達式的注解來進行權(quán)限配置,它的使用也是需要在spring-security.xml中啟用對應(yīng)的支持才會生效的,具體配置如下:
另外還需要在對應(yīng)的java類中進行注解配置:
public class UserServiceImpl implements UserService {
@PreAuthorize("hasRole('ROLE_USER')")
@Override
public void findAll() {
for (int i = 0; i < 5; i++) {
System.out.println("商品"+i);
}
}
@PreAuthorize("hasRole('ROLE_USER')")
@Override
public void find() {
System.out.println("商品");
}
@PreAuthorize("hasRole('ROLE_ADMIN')")
@Override
public void add() {
System.out.println("添加商品");
}
}
其中:
• @PreAuthorize:使用表達式設(shè)置訪問對應(yīng)方法時所應(yīng)該具有的角色。
運行測試
運行測試,當(dāng)?shù)卿洺晒χ螅?/span>
在瀏覽器輸入"http://localhost:8082/find.do",在開發(fā)工具的打印臺會打印出
如下結(jié)果: 在瀏覽器輸入"http://localhost:8082/findAll.do",在開發(fā)工具的打印臺會打印出如下結(jié)果: 在瀏覽器輸入"http://localhost:8082/add.do"
會發(fā)現(xiàn)如下結(jié)果: 根據(jù)結(jié)果會發(fā)現(xiàn)當(dāng)通過find.do或者是findAll.do進行請求時,因為配置了注解@PreAuthorize("hasRole('ROLEUSER')"),所以會直接通過controller調(diào)用service的方法來完成請求,但是當(dāng)通過add.do進行請求時,因為配置的注解是@PreAuthorize("hasRole('ROLEADMIN')"),權(quán)限不對,所以會提示訪問拒絕。
總結(jié)
方法級別的權(quán)限控制是Spring Security的權(quán)限控制方式之一,Spring Security可以通過intercept-methods對某個bean下面的方法進行權(quán)限控制,也可以通過pointcut對整個Service層的方法進行統(tǒng)一的權(quán)限控制,還可以通過注解定義對單獨的某一個方法進行權(quán)限控制,使用方法級別的權(quán)限控制,可以實現(xiàn)細粒度的權(quán)限控制,使權(quán)限控制更具體細致。
猜你喜歡:
java遞歸是什么意思,怎么用
jdk環(huán)境變量配置