一、该问题的重现步骤是什么?
1. 两个bladex平台开发的项目,一个作为统一认证平台,一个作为业务系统
2. 业务系统通过编写AuthRequest子类,通过调用/oauth/render接口方式实现统一认证平台登录
3.无法通过调用/oauth/revoke接口实现从统一认证平台注销
4.原因参考“统一认证登录后调用统一认证注销接口/oauth/authorize/logout不成功”这个问题,因为是后端通过http访问方式,所以登录和注销的session不是一个
感觉这里通过session来存储统一认证的用户信息方式不太合理,我这种因为是后端http请求调用,不是同一个session,就无法实现注销功能。或者能让http请求用同一个session,或者登录和注销不要用session存储认证用户信息。
二、你期待的结果是什么?实际看到的又是什么?
三、你正在使用的是什么产品,什么版本?在什么操作系统上?
四、请提供详细的错误堆栈信息,这很重要。
五、若有更多详细信息,请在下面提供。
spring官方也采用了session方案,具体可参考:https://docs.spring.io/spring-security/reference/servlet/authentication/persistence.html 、https://docs.spring.io/spring-security/reference/reactive/oauth2/login/logout.html , 如果你有更好更完美的方案,可提交给我们,我们研究下看看是否能实现。
spring官方相关核心类:org.springframework.security.oauth2.client.oidc.web.logout.OidcClientInitiatedLogoutSuccessHandler
简短结论:OidcClientInitiatedLogoutSuccessHandler 是 Spring Security 提供的“RP 发起 OIDC 注销”的登出成功处理器,会在应用侧登出后把 浏览器重定向 到 OP 的 end_session_endpoint,并可附带 post_logout_redirect_uri 完成回跳;它依赖已配置的 ClientRegistrationRepository 从 OIDC Discovery 读取 end_session_endpoint。
文档在“OpenID Connect 1.0 Client-Initiated Logout”一节中明确给出配置 OidcClientInitiatedServerLogoutSuccessHandler 的示例:在本地 logout 成功后,将用户代理(浏览器)重定向到 OP 的 end_session_endpoint,并可设置 post_logout_redirect_uri 回跳到应用,这就是“通过浏览器访问退出 URL”的标准实现方式。
代码示例中 setPostLogoutRedirectUri("{baseUrl}") 展示了典型的浏览器重定向退出流程:浏览器先去 OP 完成会话清理,然后再回到应用,这与 OIDC RP-Initiated Logout 规范一致。
我的理解,之所以要在session中存放和清除认证用户信息,应该是确保执行注销请求的是当前浏览器下执行认证请求的客户,避免无关客户调用注销请求。
是否可以考虑把认证用户信息存放在redis中,在客户认证成功时在redis存储该客户的clientId。
当收到注销请求时,检查是否认证过的客户clientId,如果是则允许注销,清除redis中保存的用户信息,以及存储的客户clientId,完成注销操作。
不过这个可能带来一个问题,客户在A机器登录认证,在B机器也能注销。或者在chrome浏览器中认证,在edge浏览器中注销。
还是考虑怎么实现同一个浏览器内的已认证过的客户能够注销。
那是否考虑认证时提供一个随机字符串作为客户标识码,所有的业务系统认证请求时都带上同一个客户标识码(这个在统一门户里应该是可以实现的),系统根据该客户标识码存储和查找认证用户信息。相当于代替了sessionid的作用。
另外,即使还是使用session方案,统一认证注销时是否也需要检查是否认证过的客户,即认证时在session中存储clientId,注销时检查是否认证过的clientId,这样更加安全。
扫一扫访问 Blade技术社区 移动端