无状态oAuth2社会登录应该如何实现一个REST API - Spring Boot



我的目标是在我的前端上有一个登录页面,在登录后从后端获得JWT以对进一步的请求进行身份验证。

我也想添加一个Google登录选项,但是在春季使用oAuth2客户端后,如果没有JSESSIONID cookie的状态,它将无法工作。

关于如何实现无状态oAuth2社交登录以及我自己的JWT身份验证实现,是否有一种方法或一般概念?

我尝试改变弹簧安全过滤器链配置中的状态管理,但它不起作用。

我希望得到某种令牌,返回到前端,并使用它对进一步的请求进行身份验证。

Login是一个OAuth2客户端问题,需要一个状态来存储令牌。如果客户端在服务器上,这个状态通常是session,如果在浏览器中,这个状态通常是local-storage(使用Angular这样的框架和像Angular -auth-oidc-client这样的OAuth2客户端库的应用,如果使用其他框架,寻找等价的)。

后一种趋势不是在服务器上使用中间客户端对浏览器隐藏令牌(参见我的教程中的BFF)

如果你的客户端被配置为允许从几个OpenID提供者登录,资源服务器(你的无状态REST API)必须接受来自所有这些发行者的访问令牌,如果你想用JWT解码器配置它,那么所有的OPs必须发出JWT(谷歌可能不会)。

另外,如果你想设置一些基于角色的访问控制,用户角色管理将在OPs之间展开。

避免这种多租户警告的一个选项是对所有OPs使用一个farade:具有身份联合的单个授权服务器。几乎所有的OIDC提供商都可以这样做(Keycloak, Auth0和Amazon Cognito只是示例)。然后你回到标准的单租户场景,这在Spring Boot中要简单得多。

我在教程中公开了相当多的OAuth2场景,几乎所有场景都准备好了多租户。只有那些涉及自省的不需要(像Google可能会提供的不透明令牌需要)。

我最近也遇到了类似的问题。我只能找到依赖于JSESSIONID cookie的示例。此外,我找不到任何关于如何使用SessionCreationPolicy.STATELESS实现JWT身份验证的最佳实践或建议。

最终,我想出的解决方案是结合Auth0作为提供者和自定义successHandler。Auth0处理授权,并在成功登录时向应用程序提供令牌。自定义successHandler对认证进行解析,提取ID令牌,并将该令牌作为请求参数发送重定向到应用UI。UI在客户端持久化令牌,并使用它与后端API进行身份验证。

WebSecurityConfig (uiRedirectUri - configuration属性):

fun filterChain(http: HttpSecurity): SecurityFilterChain? {
...
http.getConfigurer(OAuth2LoginConfigurer::class.java as Class<OAuth2LoginConfigurer<HttpSecurity>>)
.successHandler(SuccessfulAuthenticationHandler(uiRedirectUri))
...

SuccessfulAuthenticationHandler (extends SavedRequestAwareAuthenticationSuccessHandler):

override fun onAuthenticationSuccess(
request: HttpServletRequest?,
response: HttpServletResponse,
authentication: Authentication?
) {
val user = (authentication as OAuth2AuthenticationToken).principal as DefaultOidcUser
val idToken = user.idToken
...
val targetUrl = uiRedirectUrl + "?token=" + idToken.tokenValue
redirectStrategy.sendRedirect(request, response, targetUrl)