我想在 Spring Boot 应用程序中基于 http 动词和 url 模式切换身份验证和授权方案,下面是我的用例的简化。
大多数 /mgmt/... 请求将根据基本身份验证进行授权。
一些 /mgmt/... 将是公开的,并且不需要身份验证。
任何先前未定义的路径都应被忽略/阻止。
我的计划是定义规则并按顺序评估它们。对于本示例中使用的规则,将使用三个规则,按顺序评估,首先匹配的将被使用。
GET /mgmt/configuration/** -> Publicly open (anonymous)
ANY /mgmt/** -> ADMIN role user
ANY /** -> deny
我对公共和管理员的规则有疑问,特别是它们重叠(都以 /mgmt 开头)。如果我将公众放在它自己的上下文路径 (/public) 下,则下面的代码可以工作 - 但我不想这样做(我也无法控制这些模式)。
也许我需要按上下文路径而不是身份验证方案对配置器进行分组。配置实际上不是本示例中的静态配置,而是来自其他模块(微服务)并组装在安全库中,以尝试集中身份验证代码。
@EnableWebSecurity
public class MultiHttpSecurityConfig {
private static final String MGMT_PATTERN = "/mgmt/**";
private static final String PUBLIC_PATTERN = "/public/**";
@Configuration
@Order(1)
public static class PublicConfigurationAdapter extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher(PUBLIC_PATTERN).authorizeRequests().anyRequest().permitAll();
}
}
@Configuration
@Order(2)
public static class AdminConfigurationAdapter extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher(MGMT_PATTERN)
.authorizeRequests().anyRequest()
.hasRole("ADMIN")
.and()
.httpBasic()
.and().csrf().disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
/**
* Some operation.
*
* @return some value.
*/
@Bean
public UserDetailsService userDetailsService() {
PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
UserDetails user = User.withUsername("user")
.password(encoder.encode("password"))
.roles("ADMIN").build();
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(user);
return manager;
}
}
@Configuration
@Order(3)
public static class DenyConfigurationAdapter extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/**").authorizeRequests().anyRequest().denyAll();
}
}
}