背景:
有几个服务(spring boot REST API服务和其他一些使用REST API的产品(作为后端,一些有角度的应用程序(一些具有不同二级域名的网站(作为前端。
一个前端应用程序可以使用异步方法调用一些后端服务(它们通过反向代理位于同一域下,因此没有CORS问题(。
目标
SSO,即如果用户成功登录到前端应用程序,则该用户应访问其他应用程序,而无需再次登录。(当然,在启用cookie的同一浏览器中(
问题
- REST API应该遵循客户端证书流(如果未通过身份验证则返回401(还是身份验证代码流(如果没有通过身份验证,则返回302(
许多文档/提示/帖子建议REST API应该遵循客户端凭据流,因为它是无状态的,并且不知道重定向uri。但是,如果我没有错的话,使用Client Credentials Flow是不可能实现OSS的,否则所有后端服务都应该是keycapture中的同一个客户端,可以共享client_id
和client_secret
。
如果使用身份验证代码流,问题是前端如何在用户成功登录后检索响应数据
front-end back-end keycloak
| -- asyn call --> |
| <-- HTTP 302 -- |
| -- redirect to login page --> |
| <-- redirect to where ???-- |
如果问题1的答案遵循客户端凭据流,那么在几个后端服务之间共享相同的
client_id
和client_secret
是最佳做法吗?或者还有其他解决方案吗?如果问题2的答案是遵循验证代码流,那么在成功登录后如何处理异步REST API调用?
1.(SSO协议
应使用Open ID Connect
。理论上也有SAML
,但它是为web应用程序指定的,而不是为SPA应用程序/RESTAPI指定的。
2.(前端(SPA应用程序(管理身份验证
您需要用户标识,因此客户端凭据流不正确。你需要Authorization Code Flow with Proof Key for Code Exchange (PKCE)
。使用成熟的(OIDC认证的(库(例如。https://github.com/damienbod/angular-auth-oidc-client)并且他们将管理一切(令牌刷新、路由授权、注销…(。您不需要任何名称中带有Key斗篷的库(OIDC是标准库,必须实现,而不是Key斗篷(。Fronted向每个API请求添加访问令牌(例如,使用Angular拦截器(。
3.(后端(REST API(只验证令牌
来自前端的呼叫是XMLHttpRequest
请求,它们在后台。让302响应(重定向到auth(是没有意义的。用户将看不到这一点,所以这就是为什么应该返回401 Unauthorized
的原因(然后前端可以有自己的业务逻辑来处理这一问题,例如重定向到auth(。因此后端不需要实现任何登录流。它们只验证请求中使用的令牌的有效性。最终,他们会进行授权,例如,只有具有某些特定组/角色的用户才能执行相同的操作——只有编辑才能编辑,只有管理员才能删除,否则将使用正确的响应代码403 Forbidden
进行响应。