java - spring-boot 中存在多个 WebSecurityConfigurerAdapter 的问题

标签 java spring spring-boot spring-security

我正在使用 spring-boot-1.5.10 和 spring-boot-starter-security。 在我的微服务中,我将 API 暴露给外部世界和内部微服务。 所以我想要2种安全性。一个用于外部调用,另一个用于内部调用。

我已提及this URL 并尝试在我的应用程序中实现多个安全适配器。 但不幸的是,它总是选择内部而不是外部,

请查找安全适配器供您引用,

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired(required = false)
    ServiceWebSecurityConfigurer serviceWebSecurityConfigurer;

//    @Override
//    public void configure(WebSecurity web) throws Exception {
//        web
//                .ignoring()
//                .antMatchers(HttpMethod.PUT,"/v1/emp/**")
//                .antMatchers(HttpMethod.DELETE,"/v1/emp/**");
//    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authenticationProvider(new ExternalApiAuthenticationProvider())
                .securityContext()
                .securityContextRepository(new ExternalApiSecurityContextRepository())
                .and()
                .exceptionHandling()
                .authenticationEntryPoint(new ApiAuthenticationEntrypoint())
                .and()
                .httpBasic().disable()
                .csrf().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .antMatchers("/v1/**").fullyAuthenticated();
        if(serviceWebSecurityConfigurer != null)
            serviceWebSecurityConfigurer.configure(http);
        http.authenticationProvider(new InternalApiAuthenticationProvider())
            .securityContext()
            .securityContextRepository(new InternalApiSecurityContextRepository())
            .and()
            .exceptionHandling()
            .authenticationEntryPoint(new ApiAuthenticationEntrypoint())
            .and()
            .httpBasic().disable()
            .csrf().disable()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
            .authorizeRequests()
            .antMatchers(HttpMethod.PUT,"/v1/emp/**").fullyAuthenticated()
            .antMatchers(HttpMethod.DELETE,"/v1/emp/**").fullyAuthenticated();
    }
}

它始终选择“InternalApiSecurityContextRepository”,即使外部 API 使用内部安全性也是如此。 看来后者压倒了前者。

UPDATE-1(根据 Gaurav Srivastav 的回答)

外部API调用安全适配器:

@EnableWebSecurity
public class WebSecurityConfig {

    @Configuration
    @Order(2)
    public static class InternalSecurityConfig extends WebSecurityConfigurerAdapter {

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authenticationProvider(new InternalApiAuthenticationProvider())
                .securityContext()
                .securityContextRepository(new InternalApiSecurityContextRepository())
                .and()
                .exceptionHandling()
                .authenticationEntryPoint(new InternalApiAuthenticationEntrypoint())
                .and()
                .httpBasic().disable()
                .csrf().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .antMatchers(HttpMethod.PUT,"/v1/emp/**").fullyAuthenticated()
                .antMatchers(HttpMethod.DELETE,"/v1/emp/**").fullyAuthenticated();
        }
    }

    @Configuration
    @Order(1)
    public static class ExternalSecurityConfig extends WebSecurityConfigurerAdapter {

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authenticationProvider(new ExternalApiAuthenticationProvider())
                .securityContext()
                .securityContextRepository(new ExternalApiSecurityContextRepository())
                .and()
                .exceptionHandling()
                .authenticationEntryPoint(new ApiAuthenticationEntrypoint())
                .and()
                .httpBasic().disable()
                .csrf().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .antMatchers("/v1/**").fullyAuthenticated();
        }
    }
}

它适用于外部(因为顺序为 1),但对于内部,我们收到以下异常,并且它使用外部配置安全上下文,

An internal server error occurred.Message:An Authentication object was not found in the SecurityContext

我认为这里的问题是,我们似乎不能使用2个安全上下文。有没有办法使用不同的安全上下文?

任何提示对于解决问题都非常重要。 提前致谢。

最佳答案

您定义了多个配置并使用 @Order 注释指定顺序。

具有自己的身份验证提供程序和 URL 模式的内部配置。

@EnableWebSecurity
public class MultiHttpSecurityConfig {

    @Configuration
    @Order(1)
    public static class InternalSecurityConfig extends WebSecurityConfigurerAdapter {

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.antMatcher("/internal/**")
                .authorizeRequests().anyRequest().hasRole("ADMIN")
                .and().httpBasic().authenticationEntryPoint(authenticationEntryPoint());
        }
    }

    @Configuration
    @Order(2)
    public static class ExternalSecurityConfig extends WebSecurityConfigurerAdapter {

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.antMatcher("/external/**")
                .authorizeRequests().anyRequest().hasRole("ADMIN")
                .and().httpBasic().authenticationEntryPoint(authenticationEntryPoint());
        }
    }

通过使用下面的文章了解更多详细信息。 https://www.baeldung.com/spring-security-multiple-entry-points

关于java - spring-boot 中存在多个 WebSecurityConfigurerAdapter 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52606720/

相关文章:

java - 改进了使用 Jackson 将嵌套 JSON 对象的 boolean 值转换为 Map 的方法

java - 重复关注 javax.validation.constraints 和 javax.persistence.Column

java - 与一种风格 POI 进行多重对齐

java - 为什么未捕获异常的处理似乎发生在发生异常行为的死线程中?

linux - 全新的 Debian STS 安装在启动时崩溃

java - 异常 :java. lang.IllegalStateException:无法转换 OneToOne 映射类型的值

java - Spring Cloud Config 属性的加载优先级是什么?

java - @Autowire JpaRepository 接口(interface)类错误限定 bean

java - 判断三个点是否在同一条街道上

java - 查找Java中操作消耗的内存