SPA

时间:2018-05-29 09:57:59

标签: asp.net-core oauth-2.0 openid-connect openiddict

尝试在包含以下组件的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_tokenbad practice

  

单页应用程序(通常实现隐式授权)在任何情况下都不应获得刷新令牌。原因是这条信息的敏感性。您可以将其视为用户凭据,因为刷新令牌允许用户基本上永远保持身份验证。因此,您无法在浏览器中获取此信息,必须将其安全存储。

建议的解决方案

  

当访问令牌过期时,假设用户的SSO会话尚未过期,静默身份验证可用于在没有用户交互的情况下检索新的身份验证。

我认为当IdP和资源服务器是同一个应用程序时,Silent Authentication不适用于密码流。 IdP发布的access_token只是一条信息,可用于在资源服务器/ IdP到期后对其进行授权,客户端如何说服 IdP发布新的access_token? (不发送refresh_token

找到angular-oauth2-oidc库,使用refresh_token续订access_token

在这种情况下,续订access_token的最佳做法/解决方案是什么?

技术细节

  • 身份提供商 - ASP.NET Core + Openiddict库。
  • SPA - AngularJs应用程序。

3 个答案:

答案 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 recommendPKCE一起进行身份验证。