spring Security 代码底层流程

95 阅读3分钟

spring Security

代码底层流程:重点看三个过滤器:

  1. FilterSecurityInterceptor:是一个方法级的权限过滤器,基本位于过滤器最底部。
  2. ExceptionTranslationFilter:是一个异常的过滤器,用来处理在认证授权过程中抛出的异常
  3. UsernamePasswordAuthenticationFilter:对/login的POST请求做了拦截,效验表单中用户名密码。

两个重要的接口

  1. UserDetailsService:接口查询数据库的用户名密码的接口。

创建类继承UsernamePasswordAuthenticationFilter,重新三个方法

创建类实现UserDetailsService,编写查询数据过程,返回User对象这个User对象是安全框架提供对象

  1. PasswordEncoder:接口数据加密,用于返回User对象里面密码加密

使用这个进行数据密码加密encode("xxx")方法进行加密算法默认会生成一个加密字符串

使用matches(“xxx”,encode)进行比较对比如果是符合就会返回true否则返回false

基于角色或权限进行访问控制

  1. hasAuthority方法如果当前主体具有指定权限则返回true否则返回false
  2. hasAnyAuthority方法如果当前主体有任何提供的角色(给定的作为一个逗号分割的字符串列表)的话,返回true
  3. hasRole方法角色控制有返回true
  4. hasAnyRole方法多个角色控制逗号分割

.regexMatchers(HttpMethod.POST,"过滤的请求接口").permitAll()

\

权限注解

\

二、允许的注解

       这里主要@PreAuthorize, @PostAuthorize, @Secured这三个注解可以使用。

2.1 @Secured

       当@EnableGlobalMethodSecurity(securedEnabled=true)的时候,@Secured可以使用:

@GetMapping("/helloUser") @Secured({"ROLE_normal","ROLE_admin"}) public String helloUser() {     return "hello,user"; }

 

@GetMapping("/helloUser") @Secured({"ROLE_normal","ROLE_admin"}) public String helloUser() {     return "hello,user"; }

说明:拥有normal或者admin角色的用户都可以方法helloUser()方法。另外需要注意的是这里匹配的字符串需要添加前缀“ROLE_“。

 

       如果我们要求,只有同时拥有admin & noremal的用户才能方法helloUser()方法,这时候@Secured就无能为力了。

 

2.2 @PreAuthorize

       Spring的 @PreAuthorize/@PostAuthorize 注解更适合方法级的安全,也支持Spring 表达式语言,提供了基于表达式的访问控制。

       当@EnableGlobalMethodSecurity(prePostEnabled=true)的时候,@PreAuthorize可以使用:

 

@GetMapping("/helloUser") @PreAuthorize("hasAnyRole('normal','admin')") public String helloUser() {     return "hello,user"; }

 

说明:拥有normal或者admin角色的用户都可以方法helloUser()方法。

       此时如果我们要求用户必须同时拥有normal和admin的话,那么可以这么编码:

 

@GetMapping("/helloUser") @PreAuthorize("hasRole('normal') AND hasRole('admin')")  public String helloUser() {     return "hello,user"; }

 

       此时如果使用user/123登录的话,就无法访问helloUser()的方法了。

 

2.3 @PostAuthorize

       @PostAuthorize 注解使用并不多,在方法执行后再进行权限验证,适合验证带有返回值的权限,Spring EL 提供 返回对象能够在表达式语言中获取返回的对象returnObject。

当@EnableGlobalMethodSecurity(prePostEnabled=true)的时候,@PostAuthorize可以使用:

@GetMapping("/helloUser") @PostAuthorize(" returnObject!=null &&  returnObject.username == authentication.name") public User helloUser() {         Object pricipal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();         User user;         if("anonymousUser".equals(pricipal)) {             user = null;         }else {             user = (User) pricipal;         }         return user; }

 

       这三个最常用也就是@PreAuthorize这个注解了,在使用中主要是配合Spring EL表达式。