全国咨询/投诉热线:400-618-4000

Spring Security方法级别的权限控制

更新时间:2018年12月07日13时44分 来源:传智播客 浏览次数:

Spring Security方法级别的权限控制

引言

Spring Security是一个能够为基于Spring的企业应用系统提供安全访问控制解决方案的安全框架,它利用Spring IOC、DI和AOP功能,为企业应用系统提供声明式的安全访问控制功能,简化企业系统为了安全控制而编写大量重复代码的工作,Spring Security支持Url级别的权限控制,同样也支持方法级别的权限控制,今天主要介绍Spring Security方法级别的权限控制。

Spring Security方法级别权限控制方式

Spring Security方法级别权限控制主要有以下几种方式:

• intercept-methods定义方法权限控制。

• 使用pointcut定义方法权限控制。

• 使用JSR-250注解定义方法权限控制。

• 使用@Secured注解定义方法权限控制。

• 注解使用表达式定义方法权限控制。

项目搭建

要想实现Spring Security方法级别的权限控制,必须先将项目搭建起来。

创建名称为Spring-Security的web项目

在pom.xml文件中引入相关的依赖包。

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相关的依赖包。

• spring-webmvc是springmvc的依赖包。

• spring-security-web、spring-security-config是springsecurity相关的依赖包。

• aspectjweaver是aspectj的依赖包,用来实现pointcut方式的权限控制。

• jsr250是JSR-250标准的依赖包,用来实现jsr250注解方式的权限控制。

创建springmvc.xml和spring-security.xml配置文件。

创建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注解。

创建spring-security.xml文件,用来进行springsecurity权限控制。

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:用来设置Url权限过滤规则,其中的security属性用来设置不受权限控制的行为,intercept-url用来设置访问资源所需的权限,form-login用来设置权限不足跳转的页面,这是设置的是我们自己创建的页面,csrf是关于csrf攻击的设置。

• authentication-manager:设置认证管理器,authentication-provider是配置认证提供者,这里我们通过创建的UserDetailServiceImpl来进行实现。

配置web.xml文件

在web.xml文件中加载springmvc.xml文件和spring-security.xml文件,处理springmvc乱码问题,设置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

创建UserDetailServiceImpl

UserDetailServiceImpl用来进行权限认证,这里我们设置权限为ROLE_USER,会直接配置在spring-security.xml文件的authentication-provider中。

public class UserDetailServiceImpl implements UserDetailsService {

@Override

public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

System.out.println("经过认证类:"+username);

List authorities=new ArrayList();

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

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

}

}

创建UserController、UserService接口和UserServiceImpl接口实现类

创建UserController,调用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();

}

}

创建UserService接口

public interface UserService {

public void findAll();

public void find();

public void add();

}

创建UserServiceImpl实现UserService接口,实现具体的操作

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("添加商品");

}

}

配置权限控制所需的index.html、login.html页面

index.html

登录成功

login.html

运行测试

启动项目

SpringSecurity方法级别的权限控制

浏览器输入地址"http://localhost:8082/index.html"会出现如下效果

SpringSecurity方法级别的权限控制

: 说明权限控制已经开始起作用了,接下来就可以进行方法级别的权限控制了。
-SpringSecurity方法级别权限控制

SpringSecurity方法级别权限控制

intercept-methods方式权限控制

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

其中:

• intercept-methods:需要定义在bean元素下,定义对当前的bean的某些方法进行权限控制。

• protect:配置访问方法所需的权限,需要指定两个属性,access和method,method表示需要拦截的方法名称,可以使用通配符,access表示执行对应的方法需要拥有的权限,多个权限之间可以使用逗号分隔。

运行测试

运行测试,当登录成功之后:

在浏览器输入"http://localhost:8082/find.do",在开发工具的打印台会打印出

如下结果: 在浏览器输入"http://localhost:8082/findAll.do",在开发工具的打印台会打印出如下结果

SpringSecurity方法级别的权限控制

: 在浏览器输入"http://localhost:8082/add.do",会发现如下结果: 根据结果会发现当通过find.do或者是findAll.do进行请求时,因为在spring-security.xml文件配置了访问find*方法的访问权限是ROLEUSER,所以会直接通过controller调用service的方法来完成请求,但是当通过add.do进行请求时,因为在spring-security.xml文件配置了add方法的访问权限是ROLEADMIN,权限不对,所以会提示访问拒绝。

pointcut方式权限控制

使用pointcut方式进行权限控制,需要先引入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的方法权限控制是通过global-method-security下的protect-pointcut来定义的。

• protect-pointcut:protect-pointcut中有两个属性,expression和access,可以通过expression设置切点表达式来进行设置拦截的方法,通过access设置访问权限。

运行测试

运行测试,当登录成功之后:

在浏览器输入"http://localhost:8082/find.do",在开发工具的打印台会打印出如下结果: 在浏览器输入"http://localhost:8082/findAll.do",在开发工具的打印台会打印出如下结果: 在浏览器输入"http://localhost:8082/add.do",会发现如下结果: 根据结果会发现当通过find.do或者是findAll.do进行请求时,因为在spring-security.xml中的protect-pointcut中配置了访问find*方法的访问权限是ROLEUSER,所以会直接通过controller调用service的方法来完成请求,但是当通过add.do进行请求时,因为在spring-security.xml中的protect-pointcut配置了add方法的访问权限是ROLEADMIN,权限不对,所以会提示访问拒绝。

使用JSR-250注解方式权限控制

要使用JSR-250注解,首先需要引入jsr250依赖包,同时需要通过设置global-method-security元素的jsr250-annotation="enabled"来启用基于JSR-250注解的支持,默认为disabled,具体配置如下:

另外还需要在对应的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:设置访问对应方法时所应该具有的角色。

• @DenyAll: 表示无论什么角色都不能访问。

运行测试

运行测试,当登录成功之后:

在浏览器输入"http://localhost:8082/find.do",会发现如下结果: 在浏览器输入"http://localhost:8082/findAll.do",在开发工具的打印台会打印出如下结果

SpringSecurity方法级别的权限控制

: 在浏览器输入"http://localhost:8082/add.do",会发现如下结果: 根据结果会发现当通过findAll.do进行请求时,因为配置了注解 @RolesAllowed("ROLEUSER"),所以会直接通过controller调用service的方法来完成请求,但是通过find.do进行请求时,因为配置了@DenyAll不允许任何人访问,所以会提示访问拒绝,当通过add.do进行请求时,因为配置了@RolesAllowed("ROLEADMIN"),权限不对,所以会提示访问拒绝。

使用@Secured注解方式权限控制

@Secured是由Spring Security定义的用来支持方法权限控制的注解。它的使用也是需要启用对应的支持才会生效的。通过设置global-method-security元素的secured-annotations="enabled"可以启用,具体配置如下:

另外还需要在对应的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:设置访问对应方法时所应该具有的角色。

运行测试

运行测试,当登录成功之后:

在浏览器输入"http://localhost:8082/find.do",在开发工具的打印台会打印出如下结果: 在浏览器输入"http://localhost:8082/findAll.do",在开发工具的打印台会打印出如下结果: 在浏览器输入"http://localhost:8082/add.do",会发现如下结果:

根据结果会发现当通过find.do或者是findAll.do进行请求时,因为配置了注解@Secured("ROLEUSER"),所以会直接通过controller调用service的方法来完成请求,但是当通过add.do进行请求时,因为配置的注解是@Secured("ROLEADMIN"),权限不对,所以会提示访问拒绝。

注解使用表达式方式权限控制

Spring Security中也可以使用表达式的注解来进行权限配置,它的使用也是需要在spring-security.xml中启用对应的支持才会生效的,具体配置如下:

另外还需要在对应的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:使用表达式设置访问对应方法时所应该具有的角色。

运行测试

运行测试,当登录成功之后:

在浏览器输入"http://localhost:8082/find.do",在开发工具的打印台会打印出

SpringSecurity方法级别的权限控制

如下结果: 在浏览器输入"http://localhost:8082/findAll.do",在开发工具的打印台会打印出如下结果: 在浏览器输入"http://localhost:8082/add.do"

SpringSecurity方法级别的权限控制

会发现如下结果: 根据结果会发现当通过find.do或者是findAll.do进行请求时,因为配置了注解@PreAuthorize("hasRole('ROLEUSER')"),所以会直接通过controller调用service的方法来完成请求,但是当通过add.do进行请求时,因为配置的注解是@PreAuthorize("hasRole('ROLEADMIN')"),权限不对,所以会提示访问拒绝。

总结

方法级别的权限控制是Spring Security的权限控制方式之一,Spring Security可以通过intercept-methods对某个bean下面的方法进行权限控制,也可以通过pointcut对整个Service层的方法进行统一的权限控制,还可以通过注解定义对单独的某一个方法进行权限控制,使用方法级别的权限控制,可以实现细粒度的权限控制,使权限控制更具体细致。

猜你喜欢:
java递归是什么意思,怎么用
jdk环境变量配置

javaee

python

web

ui

cloud

test

c

netmarket

pm

Linux

movies

robot

uids

北京校区

    14天免费试学

    基础班入门课程限时免费

    申请试学名额

    15天免费试学

    基础班入门课程限时免费

    申请试学名额

    15天免费试学

    基础班入门课程限时免费

    申请试学名额

    15天免费试学

    基础班入门课程限时免费

    申请试学名额

    20天免费试学

    基础班入门课程限时免费

    申请试学名额

    8天免费试学

    基础班入门课程限时免费

    申请试学名额

    20天免费试学

    基础班入门课程限时免费

    申请试学名额

    5天免费试学

    基础班入门课程限时免费

    申请试学名额

    0天免费试学

    基础班入门课程限时免费

    申请试学名额

    12天免费试学

    基础班入门课程限时免费

    申请试学名额

    5天免费试学

    基础班入门课程限时免费

    申请试学名额

    5天免费试学

    基础班入门课程限时免费

    申请试学名额

    10天免费试学

    基础班入门课程限时免费

    申请试学名额