OAuth2 PKCE 流程 - 从单页应用程序安全地使用访问令牌
OAuth2 PKCE Flow - Using Access tokens securely from Single Page Apps
我有一个 Angular 应用程序,它使用 angular-auth-oidc-client 与 KeyCloak 服务器集成
我使用 PKCE 流程并从 Keycloak 服务器(OIDC 提供商)获取 ID 令牌、访问令牌和刷新令牌。我不需要刷新令牌,但 Keycloak 服务器似乎总是 return 即使范围不使用“offline_access”。
默认情况下,OAuth 库将所有令牌存储在会话存储中。
我已经编写了一个自定义存储来忽略刷新令牌并且不将它们存储在会话存储中。
我在网上看到会话存储不是完全安全的存储,存储型XSS攻击可以取回令牌。但是,存储型 XSS 的缓解措施是使用标准框架,例如我正在使用的 Angular。
假设存储 XSS 漏洞几乎不可能发生,上述解决方案是否安全,其中我使用会话存储中的访问令牌来调用我的后端 API。
SPA 的当前最佳实践
使用访问令牌时有更多的攻击向量和未知数,current best practice是使用一个Backend for Frontend
以便在浏览器中只使用HTTP Only SameSite=strict
个cookie。
也可以通过实用程序 API 发布 cookie,以避免影响您的整体 SPA 架构。在 Curity,我们的 SPA best practices 有这方面的更多信息,尽管这是一个棘手的流程。
还有一份 link 白皮书更深入地讨论了威胁。在某种程度上,您选择的解决方案也将取决于您的数据的价值。对于中高安全性数据解决方案,目前首选仅 cookie 解决方案。
多个 SPA 和单点登录
SSO 是身份提供者会话 cookie 的 属性,以及应用程序是否使用 OpenID Connect 参数,例如 prompt=login
和 max_age
。所以多个 SPA 仍然可以使用 BFF 解决方案实现 SSO,每个应用程序被颁发不同的令牌。
多个 SPA 在调用 API 时必须使用独立的 cookie,因此必须使用不同的 API 路由。这增加了复杂性,所以我理解这些担忧。我也喜欢 Javascript 等旧解决方案的简单性,例如 oidc-client.
攻击向量
这些包括通过获取 API 的猴子补丁在 APIs 的飞行中捕获令牌、攻击者旋转获取令牌的隐藏 iframe 或浏览器扩展的拦截操作。
如果令牌以某种方式被拦截,它们可能会被发送出浏览器。内容安全策略应该降低这种风险,但用户或插件可以禁用它们。这个video discusses threats而且还蛮有意思的。
感知
这是最重要的因素之一 - 如果您必须向客户、利益相关者或 PEN 测试人员解释您的安全性。如果您遵循 BCP,这些对话会更容易。否则,在某些领域,你可能会遇到棘手的问题。
我有一个 Angular 应用程序,它使用 angular-auth-oidc-client 与 KeyCloak 服务器集成
我使用 PKCE 流程并从 Keycloak 服务器(OIDC 提供商)获取 ID 令牌、访问令牌和刷新令牌。我不需要刷新令牌,但 Keycloak 服务器似乎总是 return 即使范围不使用“offline_access”。
默认情况下,OAuth 库将所有令牌存储在会话存储中。 我已经编写了一个自定义存储来忽略刷新令牌并且不将它们存储在会话存储中。
我在网上看到会话存储不是完全安全的存储,存储型XSS攻击可以取回令牌。但是,存储型 XSS 的缓解措施是使用标准框架,例如我正在使用的 Angular。
假设存储 XSS 漏洞几乎不可能发生,上述解决方案是否安全,其中我使用会话存储中的访问令牌来调用我的后端 API。
SPA 的当前最佳实践
使用访问令牌时有更多的攻击向量和未知数,current best practice是使用一个Backend for Frontend
以便在浏览器中只使用HTTP Only SameSite=strict
个cookie。
也可以通过实用程序 API 发布 cookie,以避免影响您的整体 SPA 架构。在 Curity,我们的 SPA best practices 有这方面的更多信息,尽管这是一个棘手的流程。
还有一份 link 白皮书更深入地讨论了威胁。在某种程度上,您选择的解决方案也将取决于您的数据的价值。对于中高安全性数据解决方案,目前首选仅 cookie 解决方案。
多个 SPA 和单点登录
SSO 是身份提供者会话 cookie 的 属性,以及应用程序是否使用 OpenID Connect 参数,例如 prompt=login
和 max_age
。所以多个 SPA 仍然可以使用 BFF 解决方案实现 SSO,每个应用程序被颁发不同的令牌。
多个 SPA 在调用 API 时必须使用独立的 cookie,因此必须使用不同的 API 路由。这增加了复杂性,所以我理解这些担忧。我也喜欢 Javascript 等旧解决方案的简单性,例如 oidc-client.
攻击向量
这些包括通过获取 API 的猴子补丁在 APIs 的飞行中捕获令牌、攻击者旋转获取令牌的隐藏 iframe 或浏览器扩展的拦截操作。
如果令牌以某种方式被拦截,它们可能会被发送出浏览器。内容安全策略应该降低这种风险,但用户或插件可以禁用它们。这个video discusses threats而且还蛮有意思的。
感知
这是最重要的因素之一 - 如果您必须向客户、利益相关者或 PEN 测试人员解释您的安全性。如果您遵循 BCP,这些对话会更容易。否则,在某些领域,你可能会遇到棘手的问题。