Spring Boot+Keycloak多Realm按端点分流登录问题求助
Spring Boot集成Keycloak多Realm:按端点自动分流登录问题
我在Spring Boot和Keycloak集成多Realm时遇到了需求实现问题。目前已在应用中配置了两个Realm的OAuth2客户端和提供者,配置如下:
spring: security: oauth2: resourceserver: jwt: issuer-uri: http://localhost:8080/auth/realms/realmuser client: provider: realmuser: props: ... realmadmin: props: ... registration: realmuser: props: ... realmadmin: props: ...
应用内多个端点受Spring Security保护,现在的问题是:访问任意受保护端点时,都会弹出Spring OAuth2的登录选择页面,必须手动选择realmuser或realmadmin才能登录,登录后功能正常。
我的需求是按端点路径自动匹配对应的Realm:访问/v1/admin/...端点时直接重定向到realmadmin的登录页,访问/v1/user/...端点时直接重定向到realmuser的登录页,不需要经过登录选择环节。
当前我的SecurityConfig配置如下:
@Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/v1/*") .hasRole("USER") .anyRequest() .authenticated() .and() .cors() .and() .csrf() .disable(); http.oauth2Login() .and() .logout() .addLogoutHandler(keycloakLogoutHandler) .logoutSuccessUrl("/"); http.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt); return http.build(); }
我已经尝试了以下三种方案,但都没能解决问题:
- 参考Spring官方文档,使用
JwtIssuerAuthenticationManagerResolver通过声明解析租户 - 使用
@RegisteredOAuth2AuthorizedClient注解 - 自定义
CustomAuthorizationRequestResolver并更新SecurityConfig:
SecurityConfig修改部分:
http.oauth2Login(oauth2Login -> oauth2Login .authorizationEndpoint(authorizationEndpoint -> authorizationEndpoint .baseUri("/oauth2/authorization") .authorizationRequestResolver(new CustomAuthorizationRequestResolver("/oauth2/authorization/realmuser", "/oauth2/authorization/realmadmin", clientRegistrationRepository())) ) )
对应的CustomAuthorizationRequestResolver实现:
public class CustomAuthorizationRequestResolver implements OAuth2AuthorizationRequestResolver { // ... 构造方法及默认解析器初始化代码 @Override public OAuth2AuthorizationRequest resolve(HttpServletRequest request) { String authorizationUri; if (request.getServletPath().startsWith("/v1/admin")) { authorizationUri = adminAuthorizationUri; } else if (request.getServletPath().startsWith("/v1/user")) { authorizationUri = userAuthorizationUri; } else { authorizationUri = "/oauth2/authorize"; } OAuth2AuthorizationRequest authorizationRequest = defaultAuthorizationRequestResolver.resolve(request); return authorizationRequest != null ? OAuth2AuthorizationRequest.from(authorizationRequest) .authorizationUri(authorizationUri) .build() : null; } @Override public OAuth2AuthorizationRequest resolve(HttpServletRequest request, String clientRegistrationId) { return defaultAuthorizationRequestResolver.resolve(request, clientRegistrationId); } }
内容的提问来源于stack exchange,提问作者alex90bar
相关产品推荐
相关产品推荐

