Spring Security 新手,我想为某些页面应用不同的领域(领域 1)登录,并为其余页面(领域 2)应用不同的登录: 尝试过:
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SecurityFilterChain configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeHttpRequests( authorize -> authorize
.requestMatchers(AntPathRequestMatcher.antMatcher("/customers")).authenticated()
)
.oauth2Login().loginPage("/oauth2/authorization/realm1");
http
.csrf().disable()
.authorizeHttpRequests( authorize -> authorize
.anyRequest().authenticated()
)
.oauth2Login().loginPage("/oauth2/authorization/realm2");
return http.build();
}
@Bean
public ClientRegistrationRepository clientRepository() {
return new InMemoryClientRegistrationRepository(realm1ClientRegistration(), realm2ClientRegistration());
}
private ClientRegistration realm1ClientRegistration() {
return ClientRegistration.withRegistrationId("webeam")
.clientId(realm1ClientId)
.clientSecret(realm1ClientSecret)
.redirectUri("{baseUrl}/login/oauth2/code/{registrationId}")
.scope("openid","groups", "profile", "email")
.clientAuthenticationMethod(ClientAuthenticationMethod.POST)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.authorizationUri(issuerUrl+realm1+"authorize")
.tokenUri(issuerUrl+realm1+"access_token")
.userInfoUri(issuerUrl+realm1+"userinfo")
.jwkSetUri(issuerUrl+realm1+"connect/jwk_uri")
.userNameAttributeName(IdTokenClaimNames.SUB)
.build();
}
private ClientRegistration realm2ClientRegistration() {
return ClientRegistration.withRegistrationId("realm2")
.clientId(realm2ClientId)
.clientSecret(realm2ClientSecret)
.redirectUri("{baseUrl}/login/oauth2/code/{registrationId}")
.scope("openid","groups", "profile", "email")
.clientAuthenticationMethod(ClientAuthenticationMethod.POST)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.authorizationUri(issuerUrl+realm2+"authorize")
.tokenUri(issuerUrl+realm2+"access_token")
.userInfoUri(issuerUrl+realm2+"userinfo")
.jwkSetUri(issuerUrl+realm2+"connect/jwk_uri")
.userNameAttributeName(IdTokenClaimNames.SUB)
.build();
}
但它似乎忽略了匹配器“/customers”并且仅默认为一个领域。
谢谢
我认为您的问题是您不断覆盖每个请求的登录页面值,这就是您最终支持单个领域的原因。我认为对你有用的是使用单独的 Spring 配置来支持你的两种场景并使你的意图更清晰。例如:
@Configuration
public class SecurityConfiguration {
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SecurityFilterChain configurationScenario1(HttpSecurity http) throws Exception {
return http
.securityMatcher("/customers/**")
.csrf(CsrfConfigurer::disable)
.authorizeHttpRequests(authorize -> authorize
.anyRequest().authenticated()
)
.oauth2Login(configurer -> configurer.loginPage("/oauth2/authorization/realm1"))
.build();
}
@Bean
@Order(Ordered.LOWEST_PRECEDENCE)
public SecurityFilterChain configurationScenario2(HttpSecurity http) throws Exception {
NegatedRequestMatcher noCustomersMatcher = new NegatedRequestMatcher(new AntPathRequestMatcher("/customers/**"));
return http
.securityMatcher(noCustomersMatcher)
.csrf(CsrfConfigurer::disable)
.authorizeHttpRequests(authorize -> authorize
.anyRequest().authenticated()
)
.oauth2Login(configurer -> configurer.loginPage("/oauth2/authorization/realm2"))
.build();
}
}
注 1:
configurationScenario1
使用 .securityMatcher("/customers")
来决定是执行其余配置还是转到下一个配置。
注意2:此配置使用Spring Security 6,而您似乎正在使用Spring Security 5,只是为了让您知道here描述的差异。