使用MSAL

时间:2018-07-13 20:03:31

标签: msal

我对OAuth2以及AccessToken和RefreshToken的概念相当熟悉。

当使用ClientApplicationBase.AcquireTokenSilentAsync()时,MSAL似乎正在为我们做一些工作。

我不清楚它是否将始终检查当前AccessToken的到期并在方法调用时自动刷新(使用RefreshToken)。

无论如何,我们应该多久调用一次AcquireTokenSilentAsync()的“最佳实践”?我们是否应该自己跟踪到期并调用此方法来更新我们的承载认证标头?我们应该在每个请求上调用AcquireTokenSilentAsync()吗? (可疑)

我看不到使用DelegateAuthenticationProvider的GraphServiceClient(正切主题,我知道)如何做任何有助于WRT刷新的事情。当令牌即将到期时,我们是否需要扩展该类并执行我们自己的刷新?我觉得这应该已经在SDK中。

感谢任何提示。 -AJ

2 个答案:

答案 0 :(得分:4)

  

目前尚不清楚它是否将始终检查当前AccessToken的到期并在方法调用时自动刷新(使用RefreshToken)。

如果我正确理解this answer,则在提供offline_access范围时会自动提供刷新令牌

  

...您已请求offline_access范围,因此您的应用将收到一个刷新令牌。

AcquireTokenSilentAsync的{​​{3}}表示,提供刷新令牌后,它将检查令牌上的到期日期,并在令牌过期或接近到期时获得一个新令牌。

  

如果访问令牌已过期或即将到期(5分钟内)    窗口),然后使用刷新令牌(如果有)来获取新    通过拨打网络访问令牌。

它将重复此行为,直到刷新令牌过期为止。 (可选)您可以通过description forceRefresh上的AcquireTokenSilentAsync参数

通过刷新令牌来强制刷新访问令牌。

utilizing

最后,我要引用enter image description here,因为它可以很好地了解MSAL和令牌

  

仅作一点说明,MSAL实际上并不发行令牌   或确定令牌到期,而是获取获得令牌   从Azure AD STS中获取。

     

MSAL到期后将自动刷新您的访问令牌   调用AcquireTokenSilentAsync时。 ....默认令牌   现在到期的是:

     

访问令牌:1小时

     

刷新令牌:90天,14天无效的滑动窗口

(17年6月13日)

  

无论如何,我们应该多久致电一次“最佳实践”   AcquireTokenSilentAsync()吗?我们应该跟踪到期时间吗   自己并调用此方法以更新我们的承载身份验证   标头?我们是否应该在每个上调用AcquireTokenSilentAsync()   请求?

this answer on SO还列出了用于呼叫AcquireTokenSilentAsync的“推荐呼叫模式”。文档documentation提到

  

对于公共客户端应用程序和机密客户端应用程序,MSAL.NET都维护令牌缓存(对于机密客户端应用程序,则维护两个缓存),并且应用程序应尝试先从缓存中获取令牌,然后再采取其他任何方法。

根据我所看到的示例,包括文档中建议的调用模式,我认为您可以简单地调用AcquireTokenSilentAsync并捕获MsalUiRequiredException作为令牌已过期的指示,并且用户必须再次登录。

  

我看不到使用DelegateAuthenticationProvider的GraphServiceClient(切线主题,我知道)如何做任何有助于刷新WRT的事情。当令牌即将到期时,我们是否需要扩展该类并执行我们自己的刷新?我觉得这应该已经在SDK中。

如果我正确理解了DelegateAuthenticationProvider,它所做的就是在将requestMessage传递给Graph之前对其进行修改。我们要做的就是为访问令牌提供请求的授权标头。我们已经知道,当我们获取访问令牌时,它是有效的,因此我们只需添加它即可。

        new DelegateAuthenticationProvider(async (requestMessage) =>
        {
            ConfidentialClientApplication cca = new ConfidentialClientApplication(_ClientId, _Authority, _RedirectUri, new ClientCredential(_ClientSecret), _UserTokenSessionCache.GetTokenCache(identifier, httpContext), _ApplicationTokenCache.GetTokenCache());
            AuthenticationResult result = await cca.AcquireTokenSilentAsync();
            requestMessage.Headers.Add("Authorization", result.CreateAuthorizationHeader());
            //OR
            requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", result.AccessToken);
        });

(设置标题的两种方法之间有also

我一直走这条路,这对我有用。我强烈建议阅读他们的文档,因为它确实对如何实现MSAL.Net提供了很好的见识。

我还没有时间来玩令牌的期限。如果没有提供刷新令牌(即使有可能的话)也没有行为

我希望这会有所帮助!

答案 1 :(得分:1)

提及上面遗漏的一件事,引用我对Get refresh token with Azure AD V2.0 (MSAL) and Asp .Net Core 2.0的回答

  
      
  • 对于上下文,OAuth 2.0 code grant flow提到了以下步骤:      
        
    • 授权,返回授权码
    •   
    • 使用auth_code来获取access_token(通常有效1小时)并刷新_token
    •   
    • access_token用于获取对相关资源的访问权限
    •   
    • access_token过期后,将使用refresh_token获取新的access_token
    •   
  •   
  • MSAL.NET通过TokenCache抽象了refresh_token的概念。      
        
    • 有一个序列化TokenCache的选项。参见Token cache serialization in MSAL.NET。这是保持登录信息黑白桌面应用程序会话并避免出现那些登录窗口的方法。
    •   
    • AcquireTokenSilentAsync是使用refresh_token获取新的access_token的过程,但这是内部完成的。有关更多详细信息和其他访问方式,请参见AcquireTokenSilentAsync using a cached token
    •   
  •   
     

希望这阐明了为什么TokenCache是​​MSAL.NET中的“新” refresh_token,而TokenCache是​​序列化和保存所需的。像Microsoft.Identity.Client.Extensions.Msal这样的库可以帮助实现这一目标。

@ AlWeber / @Raziel,以下模式适用于PublicClientApplication:

  • 在启动时,要反序列化并加载TokenCache(具有refresh_token),请尝试静默获取access_token。
  • 如果失败,请使用交互式UI来获取令牌。
  • 保存并重复使用具有AccessToken和ExpiresOn的AuthenticationResult。一旦您接近ExpiresOn属性(我个人设置为到期前30分钟),就可以重做以静默方式获取access_token(如果您是API用户,这会有点贵,因此会缓存结果)。
  

我们应该多久调用一次AcquireTokenSilentAsync()的“最佳实践”?我们是否应该自己跟踪到期并调用此方法来更新我们的承载认证标头?我们应该在每个请求上调用AcquireTokenSilentAsync()吗? (可疑)

我认为这不是一个好主意。如前所述,此调用仍然有些昂贵。另一种方法是将AuthenticationResult存储在内存中,重新使用它,然后进入仅在ExpiresOn属性附近的静默获取工作流。