教育行業(yè)A股IPO第一股(股票代碼 003032)

全國(guó)咨詢/投訴熱線:400-618-4000

Spring Security方法級(jí)別的權(quán)限控制

更新時(shí)間:2018年12月07日13時(shí)44分 來(lái)源:傳智播客 瀏覽次數(shù):

Spring Security方法級(jí)別的權(quán)限控制

引言

Spring Security是一個(gè)能夠?yàn)榛赟pring的企業(yè)應(yīng)用系統(tǒng)提供安全訪問(wèn)控制解決方案的安全框架,它利用Spring IOC、DI和AOP功能,為企業(yè)應(yīng)用系統(tǒng)提供聲明式的安全訪問(wèn)控制功能,簡(jiǎn)化企業(yè)系統(tǒng)為了安全控制而編寫大量重復(fù)代碼的工作,Spring Security支持Url級(jí)別的權(quán)限控制,同樣也支持方法級(jí)別的權(quán)限控制,今天主要介紹Spring Security方法級(jí)別的權(quán)限控制。

Spring Security方法級(jí)別權(quán)限控制方式

Spring Security方法級(jí)別權(quán)限控制主要有以下幾種方式:

• intercept-methods定義方法權(quán)限控制。

• 使用pointcut定義方法權(quán)限控制。

• 使用JSR-250注解定義方法權(quán)限控制。

• 使用@Secured注解定義方法權(quán)限控制。

• 注解使用表達(dá)式定義方法權(quán)限控制。

項(xiàng)目搭建

要想實(shí)現(xiàn)Spring Security方法級(jí)別的權(quán)限控制,必須先將項(xiàng)目搭建起來(lái)。

創(chuàng)建名稱為Spring-Security的web項(xiàng)目

在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的依賴包,用來(lái)實(shí)現(xiàn)pointcut方式的權(quán)限控制。

• jsr250是JSR-250標(biāo)準(zhǔn)的依賴包,用來(lái)實(shí)現(xiàn)jsr250注解方式的權(quán)限控制。

創(chuàng)建springmvc.xml和spring-security.xml配置文件。

創(chuàng)建springmvc.xml文件,用來(lái)掃描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是開(kāi)啟springmvc注解。

創(chuàng)建spring-security.xml文件,用來(lái)進(jìn)行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:用來(lái)設(shè)置Url權(quán)限過(guò)濾規(guī)則,其中的security屬性用來(lái)設(shè)置不受權(quán)限控制的行為,intercept-url用來(lái)設(shè)置訪問(wèn)資源所需的權(quán)限,form-login用來(lái)設(shè)置權(quán)限不足跳轉(zhuǎn)的頁(yè)面,這是設(shè)置的是我們自己創(chuàng)建的頁(yè)面,csrf是關(guān)于csrf攻擊的設(shè)置。

• authentication-manager:設(shè)置認(rèn)證管理器,authentication-provider是配置認(rèn)證提供者,這里我們通過(guò)創(chuàng)建的UserDetailServiceImpl來(lái)進(jìn)行實(shí)現(xiàn)。

配置web.xml文件

在web.xml文件中加載springmvc.xml文件和spring-security.xml文件,處理springmvc亂碼問(wèn)題,設(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用來(lái)進(jìn)行權(quán)限認(rèn)證,這里我們?cè)O(shè)置權(quán)限為ROLE_USER,會(huì)直接配置在spring-security.xml文件的authentication-provider中。

public class UserDetailServiceImpl implements UserDetailsService {

@Override

public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

System.out.println("經(jīng)過(guò)認(rèn)證類:"+username);

List authorities=new ArrayList();

authorities.add(new SimpleGrantedAuthority("ROLE_USER"));

return new User(username,"123456",authorities);

}

}

創(chuàng)建UserController、UserService接口和UserServiceImpl接口實(shí)現(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實(shí)現(xiàn)UserService接口,實(shí)現(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頁(yè)面

index.html

登錄成功

login.html

運(yùn)行測(cè)試

啟動(dòng)項(xiàng)目

SpringSecurity方法級(jí)別的權(quán)限控制

瀏覽器輸入地址"http://localhost:8082/index.html"會(huì)出現(xiàn)如下效果

SpringSecurity方法級(jí)別的權(quán)限控制

: 說(shuō)明權(quán)限控制已經(jīng)開(kāi)始起作用了,接下來(lái)就可以進(jìn)行方法級(jí)別的權(quán)限控制了。
-SpringSecurity方法級(jí)別權(quán)限控制

SpringSecurity方法級(jí)別權(quán)限控制

intercept-methods方式權(quán)限控制

在spring-security.xml文件中配置:

其中:

• intercept-methods:需要定義在bean元素下,定義對(duì)當(dāng)前的bean的某些方法進(jìn)行權(quán)限控制。

• protect:配置訪問(wèn)方法所需的權(quán)限,需要指定兩個(gè)屬性,access和method,method表示需要攔截的方法名稱,可以使用通配符,access表示執(zhí)行對(duì)應(yīng)的方法需要擁有的權(quán)限,多個(gè)權(quán)限之間可以使用逗號(hào)分隔。

運(yùn)行測(cè)試

運(yùn)行測(cè)試,當(dāng)?shù)卿洺晒χ螅?/span>

在瀏覽器輸入"http://localhost:8082/find.do",在開(kāi)發(fā)工具的打印臺(tái)會(huì)打印出

如下結(jié)果: 在瀏覽器輸入"http://localhost:8082/findAll.do",在開(kāi)發(fā)工具的打印臺(tái)會(huì)打印出如下結(jié)果

SpringSecurity方法級(jí)別的權(quán)限控制

: 在瀏覽器輸入"http://localhost:8082/add.do",會(huì)發(fā)現(xiàn)如下結(jié)果: 根據(jù)結(jié)果會(huì)發(fā)現(xiàn)當(dāng)通過(guò)find.do或者是findAll.do進(jìn)行請(qǐng)求時(shí),因?yàn)樵趕pring-security.xml文件配置了訪問(wèn)find*方法的訪問(wèn)權(quán)限是ROLEUSER,所以會(huì)直接通過(guò)controller調(diào)用service的方法來(lái)完成請(qǐng)求,但是當(dāng)通過(guò)add.do進(jìn)行請(qǐng)求時(shí),因?yàn)樵趕pring-security.xml文件配置了add方法的訪問(wèn)權(quán)限是ROLEADMIN,權(quán)限不對(duì),所以會(huì)提示訪問(wèn)拒絕。

pointcut方式權(quán)限控制

使用pointcut方式進(jìn)行權(quán)限控制,需要先引入aspectjweaver依賴包,同時(shí)需要在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)限控制是通過(guò)global-method-security下的protect-pointcut來(lái)定義的。

• protect-pointcut:protect-pointcut中有兩個(gè)屬性,expression和access,可以通過(guò)expression設(shè)置切點(diǎn)表達(dá)式來(lái)進(jìn)行設(shè)置攔截的方法,通過(guò)access設(shè)置訪問(wèn)權(quán)限。

運(yùn)行測(cè)試

運(yùn)行測(cè)試,當(dāng)?shù)卿洺晒χ螅?/span>

在瀏覽器輸入"http://localhost:8082/find.do",在開(kāi)發(fā)工具的打印臺(tái)會(huì)打印出如下結(jié)果: 在瀏覽器輸入"http://localhost:8082/findAll.do",在開(kāi)發(fā)工具的打印臺(tái)會(huì)打印出如下結(jié)果: 在瀏覽器輸入"http://localhost:8082/add.do",會(huì)發(fā)現(xiàn)如下結(jié)果: 根據(jù)結(jié)果會(huì)發(fā)現(xiàn)當(dāng)通過(guò)find.do或者是findAll.do進(jìn)行請(qǐng)求時(shí),因?yàn)樵趕pring-security.xml中的protect-pointcut中配置了訪問(wèn)find*方法的訪問(wèn)權(quán)限是ROLEUSER,所以會(huì)直接通過(guò)controller調(diào)用service的方法來(lái)完成請(qǐng)求,但是當(dāng)通過(guò)add.do進(jìn)行請(qǐng)求時(shí),因?yàn)樵趕pring-security.xml中的protect-pointcut配置了add方法的訪問(wèn)權(quán)限是ROLEADMIN,權(quán)限不對(duì),所以會(huì)提示訪問(wèn)拒絕。

使用JSR-250注解方式權(quán)限控制

要使用JSR-250注解,首先需要引入jsr250依賴包,同時(shí)需要通過(guò)設(shè)置global-method-security元素的jsr250-annotation="enabled"來(lái)啟用基于JSR-250注解的支持,默認(rèn)為disabled,具體配置如下:

另外還需要在對(duì)應(yīng)的java類中進(jìn)行注解配置:

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è)置訪問(wèn)對(duì)應(yīng)方法時(shí)所應(yīng)該具有的角色。

• @DenyAll: 表示無(wú)論什么角色都不能訪問(wèn)。

運(yùn)行測(cè)試

運(yùn)行測(cè)試,當(dāng)?shù)卿洺晒χ螅?/span>

在瀏覽器輸入"http://localhost:8082/find.do",會(huì)發(fā)現(xiàn)如下結(jié)果: 在瀏覽器輸入"http://localhost:8082/findAll.do",在開(kāi)發(fā)工具的打印臺(tái)會(huì)打印出如下結(jié)果

SpringSecurity方法級(jí)別的權(quán)限控制

: 在瀏覽器輸入"http://localhost:8082/add.do",會(huì)發(fā)現(xiàn)如下結(jié)果: 根據(jù)結(jié)果會(huì)發(fā)現(xiàn)當(dāng)通過(guò)findAll.do進(jìn)行請(qǐng)求時(shí),因?yàn)榕渲昧俗⒔?@RolesAllowed("ROLEUSER"),所以會(huì)直接通過(guò)controller調(diào)用service的方法來(lái)完成請(qǐng)求,但是通過(guò)find.do進(jìn)行請(qǐng)求時(shí),因?yàn)榕渲昧薂DenyAll不允許任何人訪問(wèn),所以會(huì)提示訪問(wèn)拒絕,當(dāng)通過(guò)add.do進(jìn)行請(qǐng)求時(shí),因?yàn)榕渲昧薂RolesAllowed("ROLEADMIN"),權(quán)限不對(duì),所以會(huì)提示訪問(wèn)拒絕。

使用@Secured注解方式權(quán)限控制

@Secured是由Spring Security定義的用來(lái)支持方法權(quán)限控制的注解。它的使用也是需要啟用對(duì)應(yīng)的支持才會(huì)生效的。通過(guò)設(shè)置global-method-security元素的secured-annotations="enabled"可以啟用,具體配置如下:

另外還需要在對(duì)應(yīng)的java類中進(jìn)行注解配置:

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è)置訪問(wèn)對(duì)應(yīng)方法時(shí)所應(yīng)該具有的角色。

運(yùn)行測(cè)試

運(yùn)行測(cè)試,當(dāng)?shù)卿洺晒χ螅?/span>

在瀏覽器輸入"http://localhost:8082/find.do",在開(kāi)發(fā)工具的打印臺(tái)會(huì)打印出如下結(jié)果: 在瀏覽器輸入"http://localhost:8082/findAll.do",在開(kāi)發(fā)工具的打印臺(tái)會(huì)打印出如下結(jié)果: 在瀏覽器輸入"http://localhost:8082/add.do",會(huì)發(fā)現(xiàn)如下結(jié)果:

根據(jù)結(jié)果會(huì)發(fā)現(xiàn)當(dāng)通過(guò)find.do或者是findAll.do進(jìn)行請(qǐng)求時(shí),因?yàn)榕渲昧俗⒔釦Secured("ROLEUSER"),所以會(huì)直接通過(guò)controller調(diào)用service的方法來(lái)完成請(qǐng)求,但是當(dāng)通過(guò)add.do進(jìn)行請(qǐng)求時(shí),因?yàn)榕渲玫淖⒔馐茾Secured("ROLEADMIN"),權(quán)限不對(duì),所以會(huì)提示訪問(wèn)拒絕。

注解使用表達(dá)式方式權(quán)限控制

Spring Security中也可以使用表達(dá)式的注解來(lái)進(jìn)行權(quán)限配置,它的使用也是需要在spring-security.xml中啟用對(duì)應(yīng)的支持才會(huì)生效的,具體配置如下:

另外還需要在對(duì)應(yīng)的java類中進(jìn)行注解配置:

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:使用表達(dá)式設(shè)置訪問(wèn)對(duì)應(yīng)方法時(shí)所應(yīng)該具有的角色。

運(yùn)行測(cè)試

運(yùn)行測(cè)試,當(dāng)?shù)卿洺晒χ螅?/span>

在瀏覽器輸入"http://localhost:8082/find.do",在開(kāi)發(fā)工具的打印臺(tái)會(huì)打印出

SpringSecurity方法級(jí)別的權(quán)限控制

如下結(jié)果: 在瀏覽器輸入"http://localhost:8082/findAll.do",在開(kāi)發(fā)工具的打印臺(tái)會(huì)打印出如下結(jié)果: 在瀏覽器輸入"http://localhost:8082/add.do"

SpringSecurity方法級(jí)別的權(quán)限控制

會(huì)發(fā)現(xiàn)如下結(jié)果: 根據(jù)結(jié)果會(huì)發(fā)現(xiàn)當(dāng)通過(guò)find.do或者是findAll.do進(jìn)行請(qǐng)求時(shí),因?yàn)榕渲昧俗⒔釦PreAuthorize("hasRole('ROLEUSER')"),所以會(huì)直接通過(guò)controller調(diào)用service的方法來(lái)完成請(qǐng)求,但是當(dāng)通過(guò)add.do進(jìn)行請(qǐng)求時(shí),因?yàn)榕渲玫淖⒔馐茾PreAuthorize("hasRole('ROLEADMIN')"),權(quán)限不對(duì),所以會(huì)提示訪問(wèn)拒絕。

總結(jié)

方法級(jí)別的權(quán)限控制是Spring Security的權(quán)限控制方式之一,Spring Security可以通過(guò)intercept-methods對(duì)某個(gè)bean下面的方法進(jìn)行權(quán)限控制,也可以通過(guò)pointcut對(duì)整個(gè)Service層的方法進(jìn)行統(tǒng)一的權(quán)限控制,還可以通過(guò)注解定義對(duì)單獨(dú)的某一個(gè)方法進(jìn)行權(quán)限控制,使用方法級(jí)別的權(quán)限控制,可以實(shí)現(xiàn)細(xì)粒度的權(quán)限控制,使權(quán)限控制更具體細(xì)致。

猜你喜歡:
java遞歸是什么意思,怎么用
jdk環(huán)境變量配置

0 分享到:
和我們?cè)诰€交談!