如何使用不同的 AuthenticationProvider 过滤 SPRING SECURITY

Posted

技术标签:

【中文标题】如何使用不同的 AuthenticationProvider 过滤 SPRING SECURITY【英文标题】:How to use different AuthenticationProvider for filter SPRING SECURITY 【发布时间】:2018-09-16 14:38:24 【问题描述】:

在我的安全层中,我使用了两个过滤器:AjaxAuthenticationFilter 和 JWTAuthenticationFilter(它们都扩展了 AbstractAuthenticationProcessingFilter)。对于第一个我只想使用 oAjaxAuhtenticationProvider,而对于第二个我只想使用 JwtAuthenticationProvider。

这是我的问题的主要原因,我无法将它们分开(authenticationProviders)。

我试过这段代码,但不起作用:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter 

    public static final String AUTHENTICATION_HEADER_NAME = "Authorization";
    public static final String AUTHENTICATION_URL = "/api/auth/login";
    public static final String REFRESH_TOKEN_URL = "/api/auth/token";
    public static final String API_ROOT_URL = "/api/**";


    @Autowired private RestAuthenticationEntryPoint authenticationEntryPoint;
    @Autowired private AjaxAwareAuthenticationSuccessHandler successHandler;
    @Autowired private AjaxAwareAuthenticationFailureHandler failureHandler;
    @Autowired private AjaxAuthenticationProvider ajaxAuthenticationProvider;
    @Autowired private JwtAuthenticationProvider jwtAuthenticationProvider;

    @Autowired private AuthenticationManager authenticationManager;
    @Autowired private ObjectMapper objectMapper;

    protected AjaxLoginProcessingFilter buildAjaxLoginProcessingFilter(String loginEntryPoint) throws Exception 
        AjaxLoginProcessingFilter filter = 
                new AjaxLoginProcessingFilter(loginEntryPoint, successHandler, failureHandler, objectMapper);
        filter.setAuthenticationManager(authenticationManager);
        return filter;
    

    protected JwtTokenAuthenticationProcessingFilter buildJwtTokenAuthenticationProcessingFilter(List<String> pathsToSkip, String pattern) 
        SkipPathRequestMatcher matcher = new SkipPathRequestMatcher(pathsToSkip, pattern);
        JwtTokenAuthenticationProcessingFilter filter = 
                new JwtTokenAuthenticationProcessingFilter(failureHandler, matcher);
        filter.setAuthenticationManager(this.authenticationManager);
        return filter;
    

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception 
        return super.authenticationManagerBean();
    



    @Override
    protected void configure(HttpSecurity http) throws Exception 
        List<String> permitAllEndpointsList = Arrays.asList(
            AUTHENTICATION_URL,
            REFRESH_TOKEN_URL,
            "/console"
        );

        http.
            csrf().disable()
            .exceptionHandling()
            .authenticationEntryPoint(this.authenticationEntryPoint)

        .and()
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS)

        .and()
            .authorizeRequests()
            .antMatchers(permitAllEndpointsList.toArray(new String[permitAllEndpointsList.size()]))
            .permitAll()
        .and()
            .authorizeRequests()
            .antMatchers(API_ROOT_URL).authenticated(); 
    

    @Configuration
    @Order(1)
    public class AjaxWebSecurityConfig extends WebSecurityConfigurerAdapter 

        @Override
        protected void configure(HttpSecurity http) throws Exception 

            http
                .csrf().disable()
                .addFilterBefore(buildAjaxLoginProcessingFilter(AUTHENTICATION_URL), UsernamePasswordAuthenticationFilter.class)
                .authenticationProvider(ajaxAuthenticationProvider);

        

    

    @Configuration
    @Order(2)
    public class JwtWebSecurityConfig extends WebSecurityConfigurerAdapter 

        @Override
        protected void configure(HttpSecurity http) throws Exception 
            List<String> permitAllEndpointsList = Arrays.asList(
                    AUTHENTICATION_URL,
                    REFRESH_TOKEN_URL,
                    "/console"
                );

            http
                .csrf().disable()
                .addFilterBefore(buildJwtTokenAuthenticationProcessingFilter(permitAllEndpointsList, API_ROOT_URL),
                    UsernamePasswordAuthenticationFilter.class)
                .authenticationProvider(jwtAuthenticationProvider);

        

    


【问题讨论】:

***.com/questions/33603156/…的可能重复 【参考方案1】:

感谢您的帮助。我的代码完全错误。错误的注释和方法。

我解决了将正确的 authManager 传递给目标配置的问题(仅考虑):

 @Configuration
    @Order(1)
    public class AjaxWebSecurityConfig extends WebSecurityConfigurerAdapter 

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception 
            // TODO Auto-generated method stub
            auth.authenticationProvider(ajaxAuthenticationProvider);
        

    

@Configuration
public class JwtWebSecurityConfig extends WebSecurityConfigurerAdapter 

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception 
            // TODO Auto-generated method stub
            auth.authenticationProvider(jwtAuthenticationProvider);
       

在 order(1) 的配置中,我必须强制定义 antMacher:

.and()
                    .antMatcher("/api/auth/**")
                    .authorizeRequests()
                    .antMatchers(AUTHENTICATION_URL)
                    .permitAll()

在最后一个配置中,我必须为“/**”定义 antMatchers

.authorizeRequests()
        .antMatchers("/**").authenticated()

最终结果:

@EnableWebSecurity
public class  WebSecurityConfig 

    public static final String AUTHENTICATION_HEADER_NAME = "Authorization";
    public static final String AUTHENTICATION_URL = "/api/auth/login";
    public static final String REFRESH_TOKEN_URL = "/api/auth/token";
    public static final String API_ROOT_URL = "/api/**";


    @Autowired private RestAuthenticationEntryPoint authenticationEntryPoint;
    @Autowired private AjaxAwareAuthenticationSuccessHandler successHandler;
    @Autowired private AjaxAwareAuthenticationFailureHandler failureHandler;
    @Autowired private AjaxAuthenticationProvider ajaxAuthenticationProvider;
    @Autowired private JwtAuthenticationProvider jwtAuthenticationProvider;

    @Autowired private ObjectMapper objectMapper;

    protected  AjaxLoginProcessingFilter buildAjaxLoginProcessingFilter(String loginEntryPoint,
            AuthenticationManager  authManager) throws Exception 
        AjaxLoginProcessingFilter filter = 
                new AjaxLoginProcessingFilter(loginEntryPoint, successHandler, failureHandler, objectMapper);
        filter.setAuthenticationManager(authManager);
        return filter;
    

    protected JwtTokenAuthenticationProcessingFilter buildJwtTokenAuthenticationProcessingFilter(String urlForFilter,
            AuthenticationManager authManager) 
        //SkipPathRequestMatcher matcher = new SkipPathRequestMatcher(pathsToSkip, pattern);
        JwtTokenAuthenticationProcessingFilter filter = 
                new JwtTokenAuthenticationProcessingFilter(failureHandler, urlForFilter);
        filter.setAuthenticationManager(authManager);
        return filter;
    

    @Configuration
    @Order(1)
    public class AjaxWebSecurityConfig extends WebSecurityConfigurerAdapter 

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception 
            // TODO Auto-generated method stub
            auth.authenticationProvider(ajaxAuthenticationProvider);
        

        @Override
        protected void configure(HttpSecurity http) throws Exception 

                http.
                    csrf().disable()
                    .exceptionHandling()
                    .authenticationEntryPoint(authenticationEntryPoint)

                .and()
                    .sessionManagement()
                    .sessionCreationPolicy(SessionCreationPolicy.STATELESS)

                .and()
                    .antMatcher("/api/auth/**")
                    .authorizeRequests()
                    .antMatchers(AUTHENTICATION_URL)
                    .permitAll()


                .and()
                    .addFilterBefore(buildAjaxLoginProcessingFilter(AUTHENTICATION_URL, super.authenticationManager()), UsernamePasswordAuthenticationFilter.class)
                    .authenticationProvider(ajaxAuthenticationProvider);

        

    

    @Configuration
    public class JwtWebSecurityConfig extends WebSecurityConfigurerAdapter 

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception 
            // TODO Auto-generated method stub
            auth.authenticationProvider(jwtAuthenticationProvider);
        

        @Override
        protected void configure(HttpSecurity http) throws Exception 

            http
                .csrf().disable()
                .authorizeRequests()
                .antMatchers("/**").authenticated()

                .and()
                .addFilterBefore(buildJwtTokenAuthenticationProcessingFilter(API_ROOT_URL, super.authenticationManager()),
                    UsernamePasswordAuthenticationFilter.class)
                .authenticationProvider(jwtAuthenticationProvider);

        

    


【讨论】:

以上是关于如何使用不同的 AuthenticationProvider 过滤 SPRING SECURITY的主要内容,如果未能解决你的问题,请参考以下文章

如何使用CSV数据集配置在Jmeter的不同线程中使用不同输入登录多个用户

如何使用 Java 在不同的线程上或作为不同的进程运行不同的 sql 查询

Blazor:如何使用来自具有 2 个不同状态的 2 个不同页面的组件

如何使用不同的表和不同的列名连接多个查询

如何使用 Xcode Storyboard 为不同的设备设置不同的字体大小?

如何在颤动中使用 textspan 用不同的装饰来装饰不同的单词