Spring Authorization Server中OIDC1.0 SLO失效问题求助
一、客户端注册时配置登出参数
Spring Authorization Server 3.1.x没有提供直接开启Front/Back-Channel Logout的配置属性,需在客户端注册时手动指定相关参数:
1. Front-Channel Logout 配置
为每个客户端(order-client、product-client)设置前端通道登出的URI和会话关联要求:
@Bean public RegisteredClientRepository registeredClientRepository() { RegisteredClient orderClient = RegisteredClient.withId(UUID.randomUUID().toString()) .clientId("order-client") .clientSecret("{noop}order-secret") .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC) .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN) .redirectUri("http://localhost:8081/login/oauth2/code/order-client") // 配置前端通道登出 .frontChannelLogoutUri("http://localhost:8081/logout") .frontChannelLogoutSessionRequired(true) .scope(OidcScopes.OPENID) .scope(OidcScopes.PROFILE) .build(); RegisteredClient productClient = RegisteredClient.withId(UUID.randomUUID().toString()) .clientId("product-client") .clientSecret("{noop}product-secret") .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC) .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN) .redirectUri("http://localhost:8082/login/oauth2/code/product-client") // 配置前端通道登出 .frontChannelLogoutUri("http://localhost:8082/logout") .frontChannelLogoutSessionRequired(true) .scope(OidcScopes.OPENID) .scope(OidcScopes.PROFILE) .build(); return new InMemoryRegisteredClientRepository(orderClient, productClient); }
2. Back-Channel Logout 配置(可选,安全性更高)
若采用后端通道,需添加对应端点配置,同时客户端要实现接收logout_token的后端接口:
// 客户端注册时追加以下配置 .backChannelLogoutUri("http://localhost:8081/api/logout/back-channel") .backChannelLogoutSessionRequired(true)
二、OP端配置登出端点
确保授权服务器启用OIDC登出功能,并配置正确的登出路径:
@Bean public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception { OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http); http.getConfigurer(OAuth2AuthorizationServerConfigurer.class) .oidc(Customizer.withDefaults()); // 启用OIDC全套功能,包含登出端点 // 配置登出路径和权限 http.logout(logout -> logout .logoutUrl("/logout") .permitAll()); http.exceptionHandling(exceptions -> exceptions .defaultAuthenticationEntryPointFor( new LoginUrlAuthenticationEntryPoint("/login"), new MediaTypeRequestMatcher(MediaType.TEXT_HTML) )); return http.build(); }
三、客户端(RP)端配置登出回调
每个客户端需配置登出逻辑,确保接收OP通知后清理本地会话:
@Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth .anyRequest().authenticated() ) .oauth2Login(Customizer.withDefaults()) .logout(logout -> logout .logoutSuccessUrl("/") .invalidateHttpSession(true) .deleteCookies("JSESSIONID") .logoutSuccessHandler(oidcLogoutSuccessHandler()) ); return http.build(); } private OidcClientInitiatedLogoutSuccessHandler oidcLogoutSuccessHandler() { OidcClientInitiatedLogoutSuccessHandler successHandler = new OidcClientInitiatedLogoutSuccessHandler(clientRegistrationRepository()); // 登出成功后跳转回客户端首页 successHandler.setPostLogoutRedirectUri("{baseUrl}/"); return successHandler; } @Autowired private ClientRegistrationRepository clientRegistrationRepository;
四、验证SLO流程
- 分别登录两个客户端,确认SSO正常
- 从order-client触发登出,会跳转至OP的登出端点
- OP会遍历当前用户的所有授权客户端,按配置发送登出通知
- 检查product-client会话是否被清理,是否需重新登录
关键注意事项
- 确保客户端与OP的URI可以互相访问,本地测试注意端口和域名一致性
- Front-Channel Logout依赖iframe加载客户端登出URI,需确保客户端允许iframe访问(必要时调整X-Frame-Options配置)
- Back-Channel Logout需客户端验证OP发送的
logout_token,确保请求合法性
内容的提问来源于stack exchange,提问作者lkpoc7
相关产品推荐
相关产品推荐

