我正在尝试将我的Spring Boot应用程序的安全性配置为具有两个单独的WebSecurityConfigurerAdapters(一个用于API调用,一个用于Web表单),并且在使配置正确工作方面遇到麻烦。
我已经使用了多个教程(https://www.baeldung.com/spring-security-multiple-entry-points)和几个堆栈溢出问题(这是最接近我的Using multiple WebSecurityConfigurerAdapter with different AuthenticationProviders (basic auth for API and LDAP for web app)的问题),但无法完成这项工作。
使用此代码,我可以使用基本身份验证发出API请求,但是当我在/login
上发帖时,我会受到405: Method not allowed
的欢迎。如果更改@Order
,则会发生相反的情况,我可以登录,但无法发出API请求(重定向到登录页面)。
SecurityConfiguration.Java
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
public class SecurityConfiguration {
@Bean(name="passwordEncoder")
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder(11);
}
@Configuration
@Order(1)
public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
private final BasicAuthenticationPoint basicAuthenticationPoint;
@Autowired
public ApiWebSecurityConfigurationAdapter(BasicAuthenticationPoint basicAuthenticationPoint){
this.basicAuthenticationPoint = basicAuthenticationPoint;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// Require API Requests to have a basic auth header
http.headers().frameOptions().disable();
http.csrf().disable();
http
.authorizeRequests().antMatchers("/api/**")
.authenticated()
.and().httpBasic().realmName("dev").authenticationEntryPoint(basicAuthenticationPoint)
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
}
@Configuration
@Order(2)
public static class FormLoginWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.headers().frameOptions().disable();
http.authorizeRequests()
.antMatchers("/register/**").permitAll()
.antMatchers("/resources/**").permitAll()
.antMatchers("/js/**").permitAll()
.antMatchers("/css/**").permitAll()
.antMatchers("/app/**").authenticated()
.antMatchers("/oauth/**").authenticated()
.anyRequest().authenticated();
http.formLogin()
.loginProcessingUrl("/login")
.loginPage("/login")
.usernameParameter("username")
.passwordParameter("password")
.defaultSuccessUrl("/app")
.failureUrl("/login")
.permitAll()
.and()
.logout()
.logoutSuccessUrl("/login")
.permitAll();
}
}
}
BasicAuthenticationPoint.java
@Component
public class BasicAuthenticationPoint extends BasicAuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authEx) throws IOException, ServletException {
response.addHeader("WWW-Authenticate", "Basic realm=" + getRealmName());
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
PrintWriter writer = response.getWriter();
writer.println("HTTP Status 401 - " + authEx.getMessage());
}
@Override
public void afterPropertiesSet() throws Exception {
setRealmName("dev");
super.afterPropertiesSet();
}
}