美文网首页Spring Security
Spring Security动态权限验证

Spring Security动态权限验证

作者: King斌 | 来源:发表于2020-07-25 01:48 被阅读0次
    @Configuration
    public class WebSerurityConfig extends WebSecurityConfigurerAdapter {
        @Autowired
        private UserServiceImpl userService;
        @Autowired
        private MyFilter filter;
        @Autowired
        private RoleAccessDecisionManager roleAccessDecisionManager;
    
        @Bean
        public PasswordEncoder passwordEncoder(){
            return new BCryptPasswordEncoder();
        }
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests()
                    .antMatchers("/student/**").hasRole("student")
                    .antMatchers("/teacher/**").hasRole("teacher")
                    .antMatchers("/admin/**").hasRole("admin")
                    .anyRequest().authenticated()
            .and().formLogin().permitAll();
        }
    
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
              ...
        }
    }
    

    从代码中,我们可以看到,每次我们添加一个角色,就需要添加角色所对应的权限路径。当我们有越来越多的角色时,我们需要不断往我们的代码中进行添加,这样做显然是很不好的。所以,接下来,我们要把角色和路径都写在数据库中,当我们添加一个角色或者修改角色对应的权限路径时,只需要往数据库进行修改即可。

    1. 获取当前路径所对应的全部权限(角色)
      将问题进行细分:

    获取当前请求路径url
    获取数据库全部有权限(角色)的url
    将当前请求url跟数据库中的url进行对比
    (1)如果在数据库中,就要获取当前请求对应的权限(角色)
    (2)如果不在,则不用返回权限信息。
    getAttributes()方法:返回本次访问需要的权限,可以有多个权限。

    @Component
    public class MyFilter implements FilterInvocationSecurityMetadataSource {
        @Autowired
        private UrlMapper urlMapper;
    
        AntPathMatcher antPathMatcher = new AntPathMatcher();
    
        /  //获取当前url对应的权限
        @Override
        public Collection<ConfigAttribute> getAttributes(Object o) throws IllegalArgumentException {
           //1.获取当前url
            String requestUrl = ((FilterInvocation) o).getRequestUrl();
            //2.获取数据库
            List<Path> allPath = pathMapper.getAllPath();
            //3.判断当前url和allPath是否匹配
            for (Path path : allPath) {
                if(new AntPathMatcher().match(path.getPattern(),requestUrl)){
                    //4.如果匹配上了,获取这个路径的权限
                    List<Role> rolesList = roleMapper.getRolesByPid(path.getId());
                    //5.返回出去
                    String [] rs = new String[rolesList.size()];
                    for (int i = 0; i < rolesList.size(); i++) {
                        rs[i] = rolesList.get(i).getRname();
                    }
                    return SecurityConfig.createList(rs);
                }
            }
           return null;
        }
    
        @Override
        public Collection<ConfigAttribute> getAllConfigAttributes() {
            return null;
        }
    
        @Override
        public boolean supports(Class<?> aClass) {
            return true;
        }
    }
    
    1. 权限决策(获取当前用户所对应的权限)
      有了权限资源,知道了当前访问的url所需要的具体权限,接下来就是决策当前的访问是否能够通过权限验证了。
      AccessDecisionManager:决策管理器
      实现AccessDecisionManager接口,自定义决策管理器。

    decide()方法有三个参数:

    authentication: 当前用户对应的信息
    object:包含客户端发起的请求的requset信息
    collection 当前路径对应的权限
    判断该用户对应的权限信息是否跟当前路径对应的权限信息相等。

    @Component
    public class RoleAccessDecisionManager implements AccessDecisionManager {
    
    
        /**
         * decide 方法是判定是否拥有权限的决策方法,
         * @param authentication 当前用户的信息
         * @param object 包含客户端发起的请求的requset信息
         * @param collection  当前路径对应的权限
         * @throws AccessDeniedException
         * @throws InsufficientAuthenticationException
         */
        @Override
        public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> collection) throws AccessDeniedException, InsufficientAuthenticationException {
            Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
            for (GrantedAuthority authority : authorities) {
                for (ConfigAttribute c : collection) {
                    if(c.getAttribute().equals(authority.getAuthority())){
                        return;
                    }
                }
            }
    
            throw new AccessDeniedException("当前访问没有权限");
        }
    
        @Override
        public boolean supports(ConfigAttribute configAttribute) {
            return true;
        }
    
        @Override
        public boolean supports(Class<?> aClass) {
            return true;
        }
    }
    
    1. 在WebSerurityConfig.java进行配置
    @Configuration
    public class WebSerurityConfig extends WebSecurityConfigurerAdapter {
        @Autowired
        private UserServiceImpl userService;
        @Autowired
        private MyFilter filter;
        @Autowired
        private RoleAccessDecisionManager roleAccessDecisionManager;
    
        @Bean
        public PasswordEncoder passwordEncoder(){
            return new BCryptPasswordEncoder();
        }
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests()
                     .withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {
                         @Override
                         public <O extends FilterSecurityInterceptor> O postProcess(O o) {
                             o.setAccessDecisionManager(roleAccessDecisionManager);
                             o.setSecurityMetadataSource(filter);
                             return o;
                         }
                     })
    //                .antMatchers("/student/**").hasRole("student")
    //                .antMatchers("/teacher/**").hasRole("teacher")
    //                .antMatchers("/admin/**").hasRole("admin")
                    .anyRequest().authenticated()
            .and().formLogin().permitAll();
        }
    
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    //        auth.inMemoryAuthentication().
    //                withUser("msj").password(passwordEncoder().encode("msj")).roles("student");
            auth.userDetailsService(userService);
        }
    }
    

    相关文章

      网友评论

        本文标题:Spring Security动态权限验证

        本文链接:https://www.haomeiwen.com/subject/arbylktx.html