Spring Security配置多个WebSecurityConfigurerAdapter遇到的问题

发布于 2022-09-13 00:23:07 字数 9649 浏览 11 评论 0

有没有了解Spring Security的大佬?请教个问题,配置多个WebSecurityConfigurerAdapter的实现,让他们使用不同的自定义认证逻辑即UserDetailsServiceImpl.loadUserByUsername()。虽然配置不同的UserDetailsServiceImpl但是会使用某个注入了authenticationManagerBeanWebSecurityConfigurerAdapter,导致所有的WebSecurityConfigurerAdapter的实现都会使用某个UserDetailsServiceImpl

代码如下:

package com.xxx.xxx.web.config;

import ...;


@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig {

    /**
     * 后台用户访问控制
     */
    @Order(2)
    @Configuration
    public static class AdminSecurityConfig extends WebSecurityConfigurerAdapter {

        /**
         * 自定义用户认证逻辑
         */
        @Qualifier("adminUserDetailsServiceImpl")
        @Autowired
        private UserDetailsService userDetailsService;

        /**
         * token认证过滤器
         */
        @Autowired
        private JwtAuthenticationAdminTokenFilter authenticationTokenFilter;

        /**
         * 退出处理类
         */
        @Autowired
        private LogoutSuccessHandlerImpl logoutSuccessHandler;



        @Bean(name = "adminAuthenticationManager")
        @Override
        public AuthenticationManager authenticationManagerBean() throws Exception {
            return super.authenticationManagerBean();
        }

        @Autowired
        @Qualifier("customAccessDeniedHandlerImpl")
        private AccessDeniedHandler accessDeniedHandler;

        /**
         * 认证失败处理类
         */
        @Autowired
        private AdminAuthenticationEntryPointImpl unauthorizedHandler;

        @Override
        protected void configure(HttpSecurity httpSecurity) throws Exception {
            httpSecurity
                    .antMatcher("/admin/**").authorizeRequests()
                    .antMatchers("/admin/login").anonymous()
                    .anyRequest().authenticated()
                    .and().csrf().disable()
                    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                    .and().exceptionHandling().accessDeniedHandler(accessDeniedHandler)
                    .and().exceptionHandling().authenticationEntryPoint(unauthorizedHandler);

            // 退出登录设置退出登录成功处理器
            httpSecurity.logout().logoutUrl("/admin/logout").logoutSuccessHandler(logoutSuccessHandler);

            // 添加JWT filter
            httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
        }


        /**
         * 身份认证接口
         */
        @Override
        protected void configure(AuthenticationManagerBuilder auth) {
            DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
            daoAuthenticationProvider.setUserDetailsService(userDetailsService);
            daoAuthenticationProvider.setPasswordEncoder(new BCryptPasswordEncoder());
            auth.authenticationProvider(daoAuthenticationProvider);
        }

    }


    /**
     * 用户端小程序访问控制
     */
    @Order(1)
    @Configuration
    public static class SellerSecurityConfig extends WebSecurityConfigurerAdapter {

        /**
         * 自定义用户认证逻辑
         */
         @Qualifier("sellerUserDetailsServiceImpl")
        @Autowired
        private UserDetailsService userDetailsService;

        /**
         * token认证过滤器
         */
        @Autowired
        private JwtAuthenticationSellerTokenFilter authenticationTokenFilter;

        /**
         * 认证失败处理类
         */
        @Autowired
        private SellerAuthenticationEntryPointImpl unauthorizedHandler;

        @Autowired
        @Qualifier("customAccessDeniedHandlerImpl")
        private AccessDeniedHandler accessDeniedHandler;

        /**
         * 退出处理类
         */
        @Autowired
        private LogoutSuccessHandlerImpl logoutSuccessHandler;



        @Override
        protected void configure(HttpSecurity httpSecurity) throws Exception {
            httpSecurity
                    .antMatcher("/seller/**").authorizeRequests()
                    .antMatchers("/seller/login").anonymous()
                    .anyRequest().authenticated()
                    .and().csrf().disable()
                    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                    .and().exceptionHandling().accessDeniedHandler(accessDeniedHandler)
                    .and().exceptionHandling().authenticationEntryPoint(unauthorizedHandler);

            // 退出登录设置退出登录成功处理器
            httpSecurity.logout().logoutUrl("/seller/logout").logoutSuccessHandler(logoutSuccessHandler);

            // 添加JWT filter
            httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
        }


        /**
         * 身份认证接口
         */
        @Override
        protected void configure(AuthenticationManagerBuilder auth) {
            DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
            daoAuthenticationProvider.setUserDetailsService(userDetailsService);
            daoAuthenticationProvider.setPasswordEncoder(new BCryptPasswordEncoder());
            auth.authenticationProvider(daoAuthenticationProvider);
        }

    }


    /**
     * 用户端小程序访问控制
     */
    @Order(0)
    @Configuration
    public static class ClientSecurityConfig extends WebSecurityConfigurerAdapter {

        /**
         * 自定义用户认证逻辑
         */
        @Qualifier("clientUserDetailsServiceImpl")
        @Autowired
        private UserDetailsService userDetailsService;

        /**
         * token认证过滤器
         */
        @Autowired
        private JwtAuthenticationClientTokenFilter authenticationTokenFilter;

        /**
         * 认证失败处理类
         */
        @Autowired
        private ClientAuthenticationEntryPointImpl unauthorizedHandler;

        @Autowired
        @Qualifier("customAccessDeniedHandlerImpl")
        private AccessDeniedHandler accessDeniedHandler;

        /**
         * 退出处理类
         */
        @Autowired
        private LogoutSuccessHandlerImpl logoutSuccessHandler;

        @Override
        protected void configure(HttpSecurity httpSecurity) throws Exception {
            httpSecurity
                    .antMatcher("/client/**").authorizeRequests()
                    .antMatchers("/client/login").anonymous()
                    .anyRequest().authenticated()
                    .and().csrf().disable()
                    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                    .and().exceptionHandling().accessDeniedHandler(accessDeniedHandler)
                    .and().exceptionHandling().authenticationEntryPoint(unauthorizedHandler);

            // 退出登录设置退出登录成功处理器
            httpSecurity.logout().logoutUrl("/client/logout").logoutSuccessHandler(logoutSuccessHandler);

            // 添加JWT filter
            httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
        }



        /**
         * 身份认证接口
         */
        @Override
        protected void configure(AuthenticationManagerBuilder auth) {
            DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
            daoAuthenticationProvider.setUserDetailsService(userDetailsService);
            daoAuthenticationProvider.setPasswordEncoder(new BCryptPasswordEncoder());
            auth.authenticationProvider(daoAuthenticationProvider);
        }

    }


    /**
     * 其他路由访问
     */
    @Configuration
    public static class OtherSecurityConfig extends WebSecurityConfigurerAdapter {

        /**
         * 认证失败处理类
         */
        @Autowired
        private OtherAuthenticationEntryPointImpl unauthorizedHandler;

        @Override
        protected void configure(HttpSecurity httpSecurity) throws Exception {
            httpSecurity
                    // CSRF禁用,因为不使用session,同时也会禁用了security默认的/login登录接口,除非再配置登录接口
                    .csrf().disable()
                    // 认证失败处理类
                    .exceptionHandling().authenticationEntryPoint(unauthorizedHandler)
                    // 基于token,所以不需要session
                    .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                    // 开始过滤 其他所有 前缀的请求
                    .and().authorizeRequests()
                    .antMatchers("/captchaImage").anonymous()
                    // 静态资源允许GET请求访问
                    .antMatchers(
                            HttpMethod.GET,
                            "/*.html",
                            "/**/*.html",
                            "/**/*.css",
                            "/**/*.js"
                    ).permitAll()
                    // 除上面外的所有请求全部需要鉴权认证
                    .anyRequest().authenticated()
                    .and().headers().frameOptions().disable();
        }


        /**
         * swagger文档显示接口,因为接口请求被spring security拦截
         * @param web
         */
        @Override
        public void configure(WebSecurity web) {
            // allow Swagger URL to be accessed without authentication
            web.ignoring().antMatchers(
                    //swagger api json
                    "/v2/api-docs",
                    //用来获取支持的动作
                    "/swagger-resources/configuration/ui",
                    //用来获取api-docs的URI
                    "/swagger-resources",
                    //安全选项
                    "/swagger-resources/configuration/security",
                    "/swagger-ui.html");
        }

    }
}

大佬们帮忙看看,不胜感激。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

孤云独去闲 2022-09-20 00:23:07

看了下源码试验了一下, configure(AuthenticationManagerBuilder auth)这个方法应该可以实现你的需求
image.png
OtherAuthenticationProvider实现了AuthenticationProvider(代码参考的DaoAuthenticationProvider ),ProviderManager.getProviders()方法返回的里面,就有我们自定义的OtherAuthenticationProvider,OtherAuthenticationProvider里面有userDetailsService和passwordEncoder字段,这样你就可以自己想传入什么实现就传入什么实现,
image.png

默认写死的10086
image.png
数据库的数据
image.png
都返回了token

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文