序
本文介绍一下spring security另外一种动态权限配置的方案
config
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public ExtAuthProvider extAuthProvider(){
return new ExtAuthProvider();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/login/**","/logout/**")
.permitAll()
.anyRequest().access("@authService.canAccess(request,authentication)");
}
这里将所有的数据权限校验交给access这个方法定义的spring el表达式
authService
@Component
public class AuthService {
public boolean canAccess(HttpServletRequest request, Authentication authentication) {
Object principal = authentication.getPrincipal();
if(principal == null){
return false;
}
if(authentication instanceof AnonymousAuthenticationToken){
//check if this uri can be access by anonymous
//return
}
Set<String> roles = authentication.getAuthorities()
.stream()
.map(e -> e.getAuthority())
.collect(Collectors.toSet());
String uri = request.getRequestURI();
//check this uri can be access by this role
return true;
}
}
这里可以单独把AnonymousAuthenticationToken拿出来校验,也可以将放到roles统一校验,其role为ROLE_ANONYMOUS
小结
使用这种方式,就没必要在每个方法上添加@PreAuthorize或者@Secured注解了,也就是不写死每个方法的权限,而是配置在数据库等其他存储,然后在AuthService里头运行时读取判断,这样就支持数据权限的动态修改和生效。
这种方法相比@PreAuthorize方式,有几点不足:
- 需要自己从request中提取参数,而且这类参数需要相对通用,比如userId,orgId等
- 对于使用PathVariable这种reset风格的参数提取相对比较费劲,而数据权限的校验往往又跟资源id是相关的