Springboot 3.x Spring Security 6 动态配置权限

@Component
public class DynamicSecurityFilter extends AbstractSecurityInterceptor implements Filter {

    @Autowired
    private MyFilter dynamicSecurityMetadataSource;

//    @Autowired
    private IgnoreUrlsConfig ignoreUrlsConfig = new IgnoreUrlsConfig();

    @Autowired
    public void setMyAccessDecisionManager(MyAccessDecisionManager dynamicAccessDecisionManager) {
        super.setAccessDecisionManager(dynamicAccessDecisionManager);
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        FilterInvocation fi = new FilterInvocation(servletRequest, servletResponse, filterChain);
        //OPTIONS请求直接放行
        if(request.getMethod().equals(HttpMethod.OPTIONS.toString())){
            fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
            return;
        }
        //白名单请求直接放行
        PathMatcher pathMatcher = new AntPathMatcher();
        for (String path : ignoreUrlsConfig.getUrls()) {
            if(pathMatcher.match(path,request.getRequestURI())){
                fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
                return;
            }
        }
        //此处会调用AccessDecisionManager中的decide方法进行鉴权操作
        InterceptorStatusToken token = super.beforeInvocation(fi);
        try {
            fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
        } finally {
            super.afterInvocation(token, null);
        }
    }

    @Override
    public void destroy() {
    }

    @Override
    public Class<?> getSecureObjectClass() {
        return FilterInvocation.class;
    }

    @Override
    public SecurityMetadataSource obtainSecurityMetadataSource() {
        return dynamicSecurityMetadataSource;
    }

}
@Configuration
@EnableWebSecurity
public class SecurityConfig   {
    Http403ForbiddenEntryPoint unauthorizedHandler =new Http403ForbiddenEntryPoint();

    @Autowired
    MyFilter myFilter;
    @Autowired
    MyAccessDecisionManager myAccessDecisionManager;

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {

        http.csrf(csrf->csrf.disable())
                .userDetailsService(userDetailsService())

                .httpBasic(withDefaults())
                .authorizeHttpRequests((authz) -> authz
                        .anyRequest().authenticated()
                               // .withObjectPostProcessor()

//                        .withObjectPostProcessor(new ObjectPostProcessor<BasicAuthenticationFilter>() {
//                            @Override
//                            public <O extends BasicAuthenticationFilter> O postProcess(O object) {
//                                object.setSecurityContextRepository(new HttpSessionSecurityContextRepository());
                                object.setAccessDecisionManager(myAccessDecisionManager);
                                object.setSecurityMetadataSource(myFilter);
//                               // object.setPublishAuthorizationSuccess(true);
//                                return object;
//                            }
//                        })
                        // 无需验证路径
//                        .requestMatchers("/public/**").permitAll()
//
//                        //.requestMatchers("/hello/**").permitAll()
//                        // 无需验证登录路径
//                        .requestMatchers("/login").permitAll()
//                        // 拥有权限才可访问
//                        .requestMatchers("/user/**").hasRole("user")//.hasAuthority("USER1")
//                        .requestMatchers("/admin/**").hasRole("admin")//.hasAuthority("USER1")
//                        .requestMatchers("/getBooks").hasRole("admin")//.hasAuthority("USER1")
//                        .requestMatchers("/aaa").hasRole("admin")//.hasAuthority("USER1")//没有权限的时候提示是404
//                        .requestMatchers("/user").hasAuthority("getAllUser")
//                        // 拥有任一权限即可访问
//                        .requestMatchers("user").hasAnyAuthority("1","2")
//                        // 角色类似,hasRole(),hasAnyRole()
//                      .anyRequest().authenticated()
                )
                // 自定义异常处理  自定义后不会调到登录界面,不知道为什么
//                .exceptionHandling(exception -> exception
//                        .authenticationEntryPoint(unauthorizedHandler)
//                        //权限不足处理
//                        .accessDeniedHandler(new AccessDeniedHandlerImpl())
//                        )//
//                .logout(httpSecurityLogoutConfigurer -> {
//                    httpSecurityLogoutConfigurer
//                            .logoutUrl("/public/logout")
//                            .logoutSuccessUrl("public/logoutSuccess");
//                           // .logoutSuccessHandler(myLogoutSuccessHandle);
//                })


                .formLogin(withDefaults())

                ;
        http.addFilterBefore(filter, FilterSecurityInterceptor.class);
         return http.build();




    }
    @Autowired DynamicSecurityFilter filter;
    @Bean
    public UserDetailsService userDetailsService() {
        return new MyUserDetailsService();
    }

//    @Bean
//    public InMemoryUserDetailsManager userDetailsService() {
//        UserDetails user = User.withDefaultPasswordEncoder()
//                .username("user")
//                .password("1234")
//                .roles("USER1","USER2")
//                //.authorities("USER1")
//                .build();
//        return new InMemoryUserDetailsManager(user);
//    }

    @Bean
    PasswordEncoder getPasswordEncoder(){
         //new BCryptPasswordEncoder();
        return NoOpPasswordEncoder.getInstance();
    }
}


//    @Bean
//    public UserDetailsManager users(DataSource dataSource) {
//        UserDetails user = User.withDefaultPasswordEncoder()
//                .username("admin")
//                .password("123")
//                .roles("USER1")
//                .build();
//        JdbcUserDetailsManager users = new JdbcUserDetailsManager(dataSource);
//        users.createUser(user);
//        return users;
//    }

//    @Bean
//    public InMemoryUserDetailsManager userDetailsService() {
//        UserDetails user = User.withDefaultPasswordEncoder()
//                .username("user")
//                .password("123")
//                .roles("USER1","USER2")
//                //.authorities("USER1")
//                .build();
//        return new InMemoryUserDetailsManager(user);
//    }
@Component
public class MyFilter implements FilterInvocationSecurityMetadataSource {
    AntPathMatcher antPathMatcher = new AntPathMatcher();


     @Autowired
    MenuRepository menuRepository;

    @Override
    public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
        String requestUrl = ((FilterInvocation)object).getRequestUrl();
        List<Menu> allMenus = menuRepository.findAll();
        for (Menu menu : allMenus) {
            if (antPathMatcher.match(menu.getPattern(), requestUrl)) {
                List<Role> roles = menu.getRoles();
                String[] roleArr = new String[roles.size()];
                for (int i = 0; i < roleArr.length; i++) {
                    roleArr[i] = roles.get(i).getName();
                }
//                org.springframework.security.access.SecurityConfig.createList()
                return org.springframework.security.access.SecurityConfig.createList(roleArr);
            }
        }
        return org.springframework.security.access.SecurityConfig.createList("ROLE_LOGIN");

       // return null;
    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }

    @Override
    public boolean supports(Class<?> clazz) {
        return true;
    }
}
@Component
public class MyAccessDecisionManager implements AccessDecisionManager {

    /**
     * @param authentication 保存了当前登录用户的信息(已有哪些角色)
     * @param o
     * @param collection     需要哪些角色,和authentication对比判断
     * @throws AccessDeniedException
     * @throws InsufficientAuthenticationException
     */
    @Override
    public void decide(Authentication authentication, Object o, Collection<ConfigAttribute> collection) throws AccessDeniedException, InsufficientAuthenticationException {
        for (ConfigAttribute attribute : collection) {//遍历collection,就是你需要的角色
            if ("ROLE_LOGIN".equals(attribute.getAttribute())) { //登录之后就可以访问
                if (authentication instanceof AnonymousAuthenticationToken) { //如果是匿名用户,说明没登录,抛异常
                    throw new AccessDeniedException("非法请求!");
                } else {
                    return;
                }
            }
            Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();//已经存在的角色/
            for (GrantedAuthority authority : authorities) {
                if (authority.getAuthority().equals(attribute.getAttribute())) { //如果存在你需要的角色,直接return
                    return;
                }
            }
        }
        throw new AccessDeniedException("非法请求!");
    }

    @Override
    public boolean supports(ConfigAttribute attribute) {
        return true;
    }

    @Override
    public boolean supports(Class<?> clazz) {
        return true;
    }
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值