项目
博客
归档
资源链接
关于我
项目
博客
归档
资源链接
关于我
Spring Security总结——授权篇
2020-11-19
·
catalina
·
转载
·
Spring Security
·
本文共 379个字,预计阅读需要 2分钟。
> 来源:[catalina_](https://www.jianshu.com/p/cba56572fec5) Spring Security是一款强大的安全认证服务框架,它的原理就是在访问我们的系统前加了一系列的过滤器,可以称为过滤器链。它的两大核心就是认证和授权,本文主要描述的授权篇。 ##### 权限表达式 springsecurity是通过权限表达式控制授权,springsecurity的权限表达式及说明如下: | 表达式 | 说明 | | :----------------------------------------: | :---------------------------------------------------: | | permitAll | 永远返回true | | denyAll | 永远返回false | | anonymous | 当前用户是anonymous时返回true | | rememberMe | 当前用户是rememberMe用户时返回true | | authenticated | 当前用户不是anonymous时返回true | | fullAuthenticated | 当前用户既不是anonymous也不是rememberMe用户时返回true | | hasRole(role) | 用户拥有指定的角色权限时返回true | | hasAnyRole([role1,role2]) | 用户拥有任意一个指定的角色权限时返回true | | hasAuthority(authority) | 用户拥有指定的权限时返回true | | hasAnyAuthority([authority1,authority2]) | 用户拥有任意一个指定的权限时返回true | | hasIpAddress('192.168.1.0') | 请求发送的Ip匹配时返回true | 接着认证部分的代码,在MySecurityConfig 的configure方法里添加需要的权限表达式: ```java @Configuration public class MySecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { // http.httpBasic() http.authorizeRequests() .antMatchers("/hello.html") .permitAll()//注意这里hello.html需要配置成不需要身份认证,否则会报重定向次数过多 .antMatchers("/user.html") // .hasRole("ADMIN")//用hasRole时,在我们返回的UserDetails的Authority需要加Role_ADMIN // .hasAuthority("read")//用户自定义的权限,返回的UserDetails的Authority只要与这里匹配就可以,这里不需要加ROLE_ // .access("hasRole('ADMIN') and hasIpAddress('192.168.0.1')")//指定有ADMIN权限并且匹配相应的IP .access("@MyRbacService.findAuthority(request,authentication)")//指定我们自己写的方法控制权限 .and() .formLogin() .loginPage("/hello.html")//指定我们自己的登录页面 .loginProcessingUrl("/admin/login")//指定让UsernamePasswordAuthenticationFilter拦截器拦截的路径 .defaultSuccessUrl("/index")//默认登录成功后跳转的页面 .and() .authorizeRequests() .anyRequest() .authenticated(); http.csrf().disable(); http.headers().frameOptions().sameOrigin(); } @Bean public PasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder(); } ``` 在强调一次,用hasRole时,在我们MyUserDetailService 返回的权限集合一定要加ROLE_ADMIN ```java @Component public class MyUserDetailService implements UserDetailsService { @Autowired private PasswordEncoder passwordEncoder; @Override public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException { return new User(name,passwordEncoder.encode("123456"), AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_ADMIN")); } } ``` 在上面配置类里用到了access,可以拼接我们自己定义的权限表达式,也可以指定我们自己写的控制权限类如.access("@MyRbacService.findAuthority(request,authentication)") 自定义权限控制类之前需要在pom里添加两个依赖 ```xml
javax.servlet
javax.servlet-api
org.springframework.security
spring-security-core
``` 对应的Service,参数需要HttpServletRequest 和Authentication ,返回值一定要是boolean: ```java public interface MyRbacService { boolean findAuthority(HttpServletRequest request, Authentication authentication); } ``` 实现类: ```java @Component("MyRbacService") public class MyRbacServiceImpl implements MyRbacService { private AntPathMatcher antPathMatcher=new AntPathMatcher(); @Override public boolean findAuthority(HttpServletRequest request, Authentication authentication) { boolean authority=false; if (authentication.getPrincipal() instanceof UserDetails){ String username = ((UserDetails) authentication.getPrincipal()).getUsername(); //根据username去数据库查询对应的url,这里就不查了 List
list =new ArrayList(); for (String url:list){ if (antPathMatcher.match(url,request.getRequestURI())){ authority=true; break; } } return authority; } return authority; } } ``` 上面代码需要在数据库创建用户表,权限表,对应url表,然后根据Authentication 里的username信息查找对应有权限的url去与当前请求url匹配,因为认证篇已经讲过,用户认证通过之后会把Authentication存在session里,所以认证过了Authentication 才会有用户信息。这里返回类型一定要是boolean,然后交给springsecurity处理。