java - 在 spring-boot 中有多个 WebSecurityConfigurerAdapter 的问题
问题描述
我正在使用 spring-boot-1.5.10 和 spring-boot-starter-security。在我的微服务中,我将 API 暴露给外部世界和内部微服务。所以我想2种安全。一个用于外部呼叫,另一个用于内部呼叫。
我已经引用了这个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),但对于内部,我们得到以下异常,它使用外部配置安全上下文,
发生内部服务器错误。消息:在 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
推荐阅读
- c - 从特定客户端接收 udp 数据包
- go - “传输:拨号 tcp 127.0.0.1:9001 时出错:连接:连接被拒绝”
- java - Java Spigot:三个不合作的类
- python - 如何获得弹性搜索查询的分数?
- jmeter - 在 JMeter 中配置日志记录时间
- authentication - 从 jwt 身份验证中的身份验证 api 获取自定义标头
- java - 如何使用分页按订单返回
- c - 我想知道为什么 &a(Data type: char) 使用 %s 打印为值而不是地址
- javascript - 根据下拉框选择显示/隐藏 div
- magento2 - 将 ScandiPWA 安装到现有的 Magento 2 设置