SpringSecurity控制授权

代码硬编码

在代码中实现适用于简单的权限控制,一般只是限制是否登录,或有简单的角色

登录与不登录

http.authorizeRequests()
    //不需要登录的路径
    .antMatchers("/orders","/login").permitAll()
    //其它需要
    .anyRequest().authenticated();

简单角色

http.authorizeRequests()
    //不需要登录的路径
    .antMatchers("/orders","/login").permitAll()
    //拥有ADMIN这个角色才能访问
    .antMatchers("/manager").hasRole("ADMIN")
    //其它需要
    .anyRequest().authenticated();

//此时用户的GrantedAuthority 为ROLE_ADMIN
new User("admin", passwordEncoder.encode("123456"),"ROLE_SECRET");

在Restful API中,有可能针对同一个请求路径,不同的请求方式需要不同的权限,此外当URL中存在参数时 如DELETE请求 user/{userId} 都是删除用户,整体URL是变化的

http.authorizeRequests()
    //路径匹配user/* 并且是delete请求 需要有ADMIN角色才能访问
    .antMatchers(HttpMethod.DELETE,"/user/*").hasRole("ADMIN")
    //其它需要
    .anyRequest().authenticated();

或者也可以搭配使用

http.authorizeRequests()
                .antMatchers(HttpMethod.DELETE,"/user/*").access("hasRole('ROLE_ADMIN') and hasRole('ROLE_SUPER') or hasIpAddress('127.0.0.1')")
                .anyRequest().authenticated();

ExpressionUrlAuthorizationConfigurer 定义的权限表达式


SpringSecurity控制授权_第1张图片
权限表达式

从数据库获取

用户权限较复杂时,不可能把每个url需要啥权限都配置在代码里,配置在代码里也无法实现动态的修改权限,实现方式貌似有两种,一种是重写 SecurityMetadataSource 和 AccessDecisionManager ,在springSecurity过滤器链中,最后一个过滤器FilterSecurityInterceptor 中会调用 AccessDecisionManager 的 decide 方法,来确定当前请求是否通过.这种方法写着比较难受,网上也有很多,就不写了.另一种就是利用SPEL 如下,表达式内的方法在 WebExpressionVoter 的 vote方法中被调用

@Component("accessDecisionService")
public class AccessDecisionService {

    private AntPathMatcher antPathMatcher = new AntPathMatcher();

    public boolean hasPermission(HttpServletRequest request, Authentication auth){
        UserDetails user = (UserDetails) auth.getPrincipal();
        String userName=user.getUsername();
        List urls=new ArrayList<>();
        //todo: 根据用户名查出能访问哪些url, urls=findUrlByUserName()
        for (String url : urls) {
            if (antPathMatcher.match(url, request.getRequestURI())){
                return true;
            }
        }
        return false;
    }
}
        http.authorizeRequests()
                .anyRequest()
                .access("@accessDecisionService.hasPermission(request , authentication)");

你可能感兴趣的:(SpringSecurity控制授权)