我尝试在 Spring Boot + Keycloak 中实现 Oath 2.0。
Spring boot 3 + Spring Security 6。
当我尝试对 Spring Boot 应用程序的后端通道注销调用 /logout 端点时,它不会重定向到 keycloak 注销端点。
在浏览器中看起来 - 没有机会逃脱((
我在调试中检查我的安全过滤器链,并了解 LogoutFilter 在任何身份验证类型过滤器之前调用。 因此,在 LogoutFilter 的内部代码中,没有机会获取填充的 Authentication 对象并下一步提取颁发者提供者 URI。
我的源代码
@Configuration
@EnableWebSecurity(debug = true)
@RequiredArgsConstructor
public class SecurityConfig {
private final CustomJwtTokenConverter customJwtTokenConverter;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.sessionManagement(session -> session
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
)
.httpBasic(AbstractHttpConfigurer::disable)
.csrf(AbstractHttpConfigurer::disable)
.cors(Customizer.withDefaults())
.oauth2Login(oauth -> oauth
.authorizationEndpoint(conf -> conf
.authorizationRedirectStrategy(redirectStrategy())
)
)
.oauth2Client(Customizer.withDefaults())
.authorizeHttpRequests(authorize -> authorize
.requestMatchers(AUTH_WHITELIST).permitAll()
.anyRequest().authenticated()
)
.oauth2ResourceServer(oauth -> oauth
.jwt(jwt -> jwt
.jwtAuthenticationConverter(customJwtTokenConverter)
)
)
.formLogin(AbstractHttpConfigurer::disable)
.rememberMe(AbstractHttpConfigurer::disable)
.logout(logout -> logout
.clearAuthentication(false)
.logoutUrl("/logout")
.logoutSuccessHandler(oidcLogoutSuccessHandler(clientRegistrationRepository)))
;
return http.build();
}
@Bean
OidcClientInitiatedLogoutSuccessHandler oidcLogoutSuccessHandler(ClientRegistrationRepository clientRegistrationRepository) {
OidcClientInitiatedLogoutSuccessHandler successHandler = new OidcClientInitiatedLogoutSuccessHandler(clientRegistrationRepository);
successHandler.setPostLogoutRedirectUri("/api");
return successHandler;
}
}
我的安全过滤器链的调试输出:
Security filter chain: [
DisableEncodeUrlFilter
WebAsyncManagerIntegrationFilter
SecurityContextHolderFilter
HeaderWriterFilter
CorsFilter
LogoutFilter
OAuth2AuthorizationRequestRedirectFilter
OAuth2AuthorizationRequestRedirectFilter
OAuth2LoginAuthenticationFilter
DefaultLoginPageGeneratingFilter
DefaultLogoutPageGeneratingFilter
BearerTokenAuthenticationFilter
RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
AnonymousAuthenticationFilter
OAuth2AuthorizationCodeGrantFilter
SessionManagementFilter
ExceptionTranslationFilter
AuthorizationFilter
]
@jzheaux 如果你能回答那就太好了!
您尝试做的事情不符合任何标准。
OpenID Connect Back-Channel Logout 用于 OP 通知 RP 注销。 IE。当您注销 Keycloak 时,它会通过后台通道注销您的应用程序。 Spring Security 刚刚在 6.2.0-M3 中合并了此功能,因此发布时将在 6.2.0 中。
如果你想将其重定向到 Keycloak 注销端点,那么你不应该更新吗
@Bean
OidcClientInitiatedLogoutSuccessHandler oidcLogoutSuccessHandler(ClientRegistrationRepository clientRegistrationRepository) {
OidcClientInitiatedLogoutSuccessHandler successHandler = new OidcClientInitiatedLogoutSuccessHandler(clientRegistrationRepository);
successHandler.setPostLogoutRedirectUri("https://keycloak/realms/myrealm/protocol/openid-connect/logout");
return successHandler;
}
如果您不希望它重定向浏览器,您可以修改重定向策略以使用Web客户端调用它。