【发布时间】:2020-04-12 13:18:03
【问题描述】:
我有一个带有以下安全配置的 REST API -
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Value("${auth0.audience}")
private String audience;
@Value("${auth0.issuer}")
private String issuer;
@Override
protected void configure(HttpSecurity http) {
try {
http.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/purch").authenticated()
.antMatchers("/purch2").authenticated();
JwtWebSecurityConfigurer
.forRS256(audience, issuer)
.configure(http);
} catch (Exception ex) {
throw new AuthenticationException(ex.getMessage());
}
}
}
我已经为这个 REST API 添加了 Swagger 文档,我正在尝试使用 this example 使用 HTTP Basic Auth 来保护 swagger 文档
因此,我用@Order(1) 更新了上面的WebSecurityConfig,并用Order(2) 添加了一个新的WebSecurityConfig,如下所示 -
@Configuration
@Order(2)
public class SwaggerSecurity extends WebSecurityConfigurerAdapter {
private static final String[] AUTH_LIST = { //
"**/v2/api-docs", //
"**/configuration/ui", //
"**/swagger-resources", //
"**/configuration/security", //
"**/swagger-ui.html", //
"**/webjars/**" //
};
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers(AUTH_LIST).authenticated().and().httpBasic();
}
//@Override
@Autowired
protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password(passwordEncoder().encode("password")).roles("USER")
.and()
.withUser("admin").password(passwordEncoder().encode("admin")).roles("USER", "ADMIN");
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
这似乎没有任何效果,也没有提示输入基本身份验证凭据。 我尝试了here、here 和here 的几种答案组合......但我无法让这个工作!
我能够让独立的Order(2) spring web 安全配置按预期工作,只是没有与Order(1) 安全配置结合使用。
正如您从我的问题中看到的那样,我不是 Spring Security 方面的专家,并尽可能多地尝试调试它!在这件事上浪费了几个小时后,我是时候寻求帮助了。任何帮助表示赞赏。谢谢。
基于 cmets 的更新: 我已经尝试将 Web Security Config 类与here 或here 显示的类似。结果是,受“授权标头”承载身份验证保护的原始 REST API 现在被基本身份验证覆盖。
可能是,我的问题是 - 我如何确保一个 Web 安全配置不会覆盖另一个?
@Configuration
@Order(2)
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Value("${auth0.audience}")
private String audience;
@Value("${auth0.issuer}")
private String issuer;
@Override
protected void configure(HttpSecurity http) {
try {
http.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/purch").authenticated()
.antMatchers("/purch2").authenticated();
JwtWebSecurityConfigurer
.forRS256(audience, issuer)
.configure(http);
} catch (Exception ex) {
throw new AuthenticationException(ex.getMessage());
}
}
@Configuration
@Order(1)
public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
private static final String[] AUTH_LIST = { //
"/v2/api-docs", //
"/configuration/ui", //
"/swagger-resources", //
"/configuration/security", //
"/swagger-ui.html", //
"/webjars/**" //
};
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests().antMatchers("/purch/**").permitAll().and()
.authorizeRequests()
.antMatchers(AUTH_LIST)
.authenticated()
.and()
.httpBasic();
}
@Autowired
protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password(passwordEncoder().encode("password")).roles("USER")
.and()
.withUser("admin").password(passwordEncoder().encode("admin")).roles("USER", "ADMIN");
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
}
【问题讨论】:
-
如果您在此处参考答案 -> stackoverflow.com/a/35405109/905494,您将看到您需要相同的 AuthenticationManagerBuilder 来配置所有身份验证提供程序。因此,基本上将安全配置类合二为一并配置身份验证提供程序可能会解决您的问题。也可以看看这个例子:baeldung.com/spring-security-multiple-auth-providers
-
@tksilicon - 感谢您的回复。我已经尝试过了,结果是我原来的基于 REST API 标头的身份验证被我添加的基本身份验证覆盖。用我的组合实现更新了上面的代码。
-
Spring 在他们的参考文献中有一个own section,它展示了如何设置多个
HttpSecurity配置 -
@Satya 我认为实现它的两种方法是拥有多重安全性或使用相同的身份验证构建器。从名称来看,如果您不想订购身份验证,则应使用 authenticationbuilder。可能通过的第一个成为订单 1,但使用多安全性,您可以订购它。
标签: java spring spring-boot