Spring boot Spring security为不同的URL使用不同的WebSecurity配置适配器

Spring boot Spring security为不同的URL使用不同的WebSecurity配置适配器,spring-boot,authentication,spring-security,jwt,Spring Boot,Authentication,Spring Security,Jwt,在spring security中,我需要对不同的路径使用两种身份验证方式。例如,我希望对/panel/**使用UserDetailService(由spring默认提供)身份验证,并希望使用自定义身份验证提供程序连接/member/**的第三方服务。但我只能同时使用其中一个身份验证提供程序。如何按路径uri分别使用它们 第一身份验证配置 @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled =

在spring security中,我需要对不同的路径使用两种身份验证方式。例如,我希望对
/panel/**
使用UserDetailService(由spring默认提供)身份验证,并希望使用自定义身份验证提供程序连接
/member/**
的第三方服务。但我只能同时使用其中一个身份验证提供程序。如何按路径uri分别使用它们

第一身份验证配置

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Order(1)
public class ApiSecurityConfig extends WebSecurityConfigurerAdapter {


    @Autowired
    @Qualifier("panelUserDetailsService")
    private PinpongPanelUserDetailService panelUserDetailsService;

    @Autowired
    private JwtRequestFilter jwtRequestFilter;

    public ApiSecurityConfig(PinpongPanelUserDetailService panelUserDetailService, JwtRequestFilter jwtRequestFilter){
        this.panelUserDetailsService = panelUserDetailService;
        this.jwtRequestFilter = jwtRequestFilter;

    }

    @Autowired
    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        // configure AuthenticationManager so that it knows from where to load
        // user for matching credentials
        // Use BCryptPasswordEncoder
        auth.userDetailsService(panelUserDetailsService).passwordEncoder(passwordEncoder());

    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

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

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        // We don't need CSRF for this example
        httpSecurity.csrf().disable().
                // dont authenticate this particular request
                authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers("/panel/authenticate").permitAll()
                .antMatchers("/panel/**").hasRole(PredifinedRole.PANEL_USER.getRole())
                .anyRequest().authenticated()

                // all other requests need to be authenticate
                .and().sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        // Add a filter to validate the tokens with every request
        httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
        httpSecurity
                .exceptionHandling()
                .authenticationEntryPoint((request, response, e) ->
                {
                    response.setContentType("application/json;charset=UTF-8");
                    response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                    response.getWriter().write(new  JSONObject()
                            .put("timestamp", LocalDateTime.now())
                            .put("message", "Access denied")
                            .toString());
                });
    }



}
@Configuration
@EnableWebSecurity
@Order(2)
public class MobileClientSecurityConfig extends WebSecurityConfigurerAdapter {

    //My custom authentication provider that connect third-party service
    @Autowired
    private UniversityMemberAuthenticationProvider authProvider;

    @Autowired
    private MobileRequestFilter mobileRequestFilter;


    @Autowired
    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authProvider);
    }



    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        // We don't need CSRF for this example
        httpSecurity.csrf().disable().
                // dont authenticate this particular request
                        authorizeRequests()
                .antMatchers("/member/authenticate").permitAll()
                .antMatchers("/member/**").hasRole(PredifinedRole.UNIVERSITY_MEMBER.getRole())
                .anyRequest().permitAll()

                // all other requests need to be authenticate
                .and().sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        // Add a filter to validate the tokens with every request
        httpSecurity.addFilterBefore(mobileRequestFilter, UsernamePasswordAuthenticationFilter.class);
        httpSecurity
                .exceptionHandling()
                .authenticationEntryPoint((request, response, e) ->
                {
                    response.setContentType("application/json;charset=UTF-8");
                    response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                    response.getWriter().write(new JSONObject()
                            .put("timestamp", LocalDateTime.now())
                            .put("message", "Access denied")
                            .toString());
                });
    }
}
第二身份验证配置

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Order(1)
public class ApiSecurityConfig extends WebSecurityConfigurerAdapter {


    @Autowired
    @Qualifier("panelUserDetailsService")
    private PinpongPanelUserDetailService panelUserDetailsService;

    @Autowired
    private JwtRequestFilter jwtRequestFilter;

    public ApiSecurityConfig(PinpongPanelUserDetailService panelUserDetailService, JwtRequestFilter jwtRequestFilter){
        this.panelUserDetailsService = panelUserDetailService;
        this.jwtRequestFilter = jwtRequestFilter;

    }

    @Autowired
    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        // configure AuthenticationManager so that it knows from where to load
        // user for matching credentials
        // Use BCryptPasswordEncoder
        auth.userDetailsService(panelUserDetailsService).passwordEncoder(passwordEncoder());

    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

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

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        // We don't need CSRF for this example
        httpSecurity.csrf().disable().
                // dont authenticate this particular request
                authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers("/panel/authenticate").permitAll()
                .antMatchers("/panel/**").hasRole(PredifinedRole.PANEL_USER.getRole())
                .anyRequest().authenticated()

                // all other requests need to be authenticate
                .and().sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        // Add a filter to validate the tokens with every request
        httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
        httpSecurity
                .exceptionHandling()
                .authenticationEntryPoint((request, response, e) ->
                {
                    response.setContentType("application/json;charset=UTF-8");
                    response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                    response.getWriter().write(new  JSONObject()
                            .put("timestamp", LocalDateTime.now())
                            .put("message", "Access denied")
                            .toString());
                });
    }



}
@Configuration
@EnableWebSecurity
@Order(2)
public class MobileClientSecurityConfig extends WebSecurityConfigurerAdapter {

    //My custom authentication provider that connect third-party service
    @Autowired
    private UniversityMemberAuthenticationProvider authProvider;

    @Autowired
    private MobileRequestFilter mobileRequestFilter;


    @Autowired
    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authProvider);
    }



    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        // We don't need CSRF for this example
        httpSecurity.csrf().disable().
                // dont authenticate this particular request
                        authorizeRequests()
                .antMatchers("/member/authenticate").permitAll()
                .antMatchers("/member/**").hasRole(PredifinedRole.UNIVERSITY_MEMBER.getRole())
                .anyRequest().permitAll()

                // all other requests need to be authenticate
                .and().sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        // Add a filter to validate the tokens with every request
        httpSecurity.addFilterBefore(mobileRequestFilter, UsernamePasswordAuthenticationFilter.class);
        httpSecurity
                .exceptionHandling()
                .authenticationEntryPoint((request, response, e) ->
                {
                    response.setContentType("application/json;charset=UTF-8");
                    response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                    response.getWriter().write(new JSONObject()
                            .put("timestamp", LocalDateTime.now())
                            .put("message", "Access denied")
                            .toString());
                });
    }
}

您需要在顶层为每个配置指定一个
antMatcher
(在
authorizeRequests
之前)。请参阅@EleftheriaStein Kousathana。除此之外,每个配置都使用相同的身份验证管理器。我正在寻找每个配置都可以使用自己的身份验证管理器的方式。也感谢您的评论