spring-boot 中有多个 WebSecurityConfigurerAdapter 的问题 [英] Issue with having multiple WebSecurityConfigurerAdapter in spring-boot

查看:67
本文介绍了spring-boot 中有多个 WebSecurityConfigurerAdapter 的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using spring-boot-1.5.10 and spring-boot-starter-security. In my microservice, I am exposing API's to the external world and internal microservices. so I would like to 2-kind of security. one for external calls and other for internal calls.

我参考了这个 URL 并尝试在我的申请.但不幸的是,它总是选择内部而不是外部,

I have referred this URL and tried to implement multiple security adapters in my application. But no luck it's always picking the internal one instead of external one,

请找到安全适配器以供参考,

Please find the security adapter for your reference,

@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.似乎后者压倒了前者.

It always picks the "InternalApiSecurityContextRepository" even the external API's using internal security. It seems the later is overriding the former.

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

外部 API 调用安全适配器:

External API call security adapter :

@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)但对于内部我们得到以下异常并且它使用外部配置安全上下文,

It works for External(Since the order is 1) but for internal we are getting the following exception and it is using the External configuration security context,

发生内部服务器错误.消息:在 SecurityContext 中找不到身份验证对象

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

我认为这里的问题是,我们似乎不能使用 2-security 上下文.无论如何要使用不同的安全上下文?

I think the problem here is, we cannot use 2-security context it seems.Is there anyway to use different security context?

任何提示对于解决问题都非常有用.提前致谢.

Any hint would be really appreciable to solve the issue. Thanks in Advance.

推荐答案

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

You have define more than one configuration and specify the order using @Order annotation.

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

Internal Configuration with its own authentication provider and url pattern.

@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-点

Get more detail through using below article. https://www.baeldung.com/spring-security-multiple-entry-points

这篇关于spring-boot 中有多个 WebSecurityConfigurerAdapter 的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆