尝试在包含以下组件的Web应用程序中实现OpenId Connect
Identity Provider和Resource Server是相同的应用程序。
SPA使用密码流来获取access_token
并存储到cookie中。 将access_token
存储到Cookie中有security threads,但这是一个不同的故事。
问题
IdP发布的 access_token
在30分钟后过期,SPA需要续订令牌而不再要求用户提供凭据。
解决方案
IdP会返回refresh_token
以及access_token
。当SPA从资源服务器获得401
时,它会将refresh_token
发送给IdP并返回新的access_token
。
问题
向SPA发送refresh_token
为bad practice。
单页应用程序(通常实现隐式授权)在任何情况下都不应获得刷新令牌。原因是这条信息的敏感性。您可以将其视为用户凭据,因为刷新令牌允许用户基本上永远保持身份验证。因此,您无法在浏览器中获取此信息,必须将其安全存储。
建议的解决方案
当访问令牌过期时,假设用户的SSO会话尚未过期,静默身份验证可用于在没有用户交互的情况下检索新的身份验证。
我认为当IdP和资源服务器是同一个应用程序时,Silent Authentication不适用于密码流。 IdP发布的access_token
只是一条信息,可用于在资源服务器/ IdP到期后对其进行授权,客户端如何说服 IdP发布新的access_token
? (不发送refresh_token
)
找到angular-oauth2-oidc库,使用refresh_token
续订access_token
。
在这种情况下,续订access_token
的最佳做法/解决方案是什么?
技术细节
答案 0 :(得分:1)
单页应用程序不得接收刷新令牌。这已经在OAuth 2.0和OpenID Connect中建立了规则。
我在这里看到的一个好方法是使用Implicit Flow。这将建立从浏览器到身份提供商的前台通道会话。使用密码授予类型,您可以进行反向呼叫(POST),因此您无法获得此类会话。
通常这是一个cookie,它指向有关以前登录状态的信息(这些是身份提供者细节)。完成流程后,SPA将收到access token
。如你所知,它将过期。但是一旦发生这种情况,SPA可以触发另一个隐式流,但这次使用prompt
查询参数。
<强>提示强>
空格分隔,区分大小写的ASCII字符串值列表 指定授权服务器是否提示最终用户 重新认证和同意。定义的值为:无,登录,同意和 select_account
如果您的身份提供者维持一个长期会话(例如: - 几小时或几天)或者如果它保持记住我的cookie,SPA可以使用prompt=none
使其从身份提供者跳过登录步骤。基本上,您正在使用此基于浏览器的SSO行为。
答案 1 :(得分:1)
使用资源所有者密码凭据流会破坏刷新令牌存储参数:而不是无法将刷新令牌存储在安全位置,SPA现在必须将资源所有者凭据存储在安全的位置(假设您希望避免经常向用户请求用户名/密码)。 Implicit补助金是专为SPA使用而设计的,因此最好坚持使用。
答案 2 :(得分:0)
除了先前的答案之外,最新的OAuth工作组guidance for SPAs不再建议使用隐式流程。
如果您有简单的共享域应用程序(单个域上的IdP,RS和客户端),则应考虑完全不使用OAuth。来自the doc:
OAuth和OpenID Connect在此方面提供的好处很小 部署方案,因此建议您重新考虑是否 在这种情况下,完全不需要OAuth或OpenID Connect。届会 身份验证的好处是活动部件更少,更少 攻击媒介。 OAuth和OpenID Connect主要是为 第三方或联邦对API的访问,因此可能不是最好的方法 同一域中的解决方案。
如果您正在在SPA中使用OIDC / OAuth,则they recommend与PKCE一起进行身份验证。