Azure - AD - AcquireTokenSilent 给出错误 failed_to_acquire_token

Azure - AD - AcquireTokenSilent giving error failed_to_acquire_token_silently(Azure - AD - AcquireTokenSilent 给出错误 failed_to_acquire_token_silently)
本文介绍了Azure - AD - AcquireTokenSilent 给出错误 failed_to_acquire_token_silently的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

我们使用 Azure AD 进行身份验证并每 30 分钟获取一次刷新的访问令牌.我们调用下面的方法来获取安全令牌并将其添加到请求头中.

We are using Azure AD to authenticate and get the refreshed access token every 30 mins. We invoke below method which acquires security token and add it to request header.

var userObjectId = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
var authContext = new AuthenticationContext(Authority, new NaiveSessionCache(userObjectId));
var credential = new ClientCredential(ConfigurationManager.AppSettings["ida:ClientId"],
ConfigurationManager.AppSettings["ida:ClientSecret"]);

    try
    {
    var authenticationResult = authContext.AcquireTokenSilent(ConfigurationManager.AppSettings["WebAPIBaseAddress"], credential, new UserIdentifier(userObjectId, UserIdentifierType.UniqueId));
    //set cookie for azure oauth refresh token - on successful login
    var httpCookie = HttpContext.Current.Response.Cookies["RefreshToken"];
    if (httpCookie != null)
        httpCookie.Value = authenticationResult.RefreshToken;

    request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authenticationResult.AccessToken);
    }
    catch
    {
    //Get access token using Refresh Token 
    var authenticationResult = authContext.AcquireTokenByRefreshToken(httpCookie.Value, credential, ConfigurationManager.AppSettings["WebAPIBaseAddress"]);
    }

在上述方法中,我们使用了 AcquireTokenSilent 方法,它为我们提供了访问令牌.由于访问令牌仅持续一段时间.过期后,我们调用 AcquireTokenByRefreshToken 获取刷新令牌.

In above method, we have used AcquireTokenSilent method which gives us access token. Since access token lasts only for certain period of time. After its expiry, we call AcquireTokenByRefreshToken to get refresh token.

上面的代码运行良好,但是我们随机出现以下异常:

The above code works well, however we are getting below exception randomly:

Microsoft.IdentityModel.Clients.ActiveDirectory.AdalSilentTokenAcquisitionException: Failed to acquire token silently. Call method AcquireToken 
   at Microsoft.IdentityModel.Clients.ActiveDirectory.AcquireTokenSilentHandler.SendTokenRequestAsync() 
   at Microsoft.IdentityModel.Clients.ActiveDirectory.AcquireTokenHandlerBase.<RunAsync>d__0.MoveNext()
ErrorCode: failed_to_acquire_token_silently

这种不一致的行为可能是什么原因?相同的代码在少数环境(Stage/Dev)上工作,但它在生产环境中随机抛出错误.

What could be the reason of such inconsistent behaviour? The same code is working on few environments (Stage/Dev) but its throwing error randomly on Production.

请提出建议.

推荐答案

我们能够解决这个问题.这似乎是代码本身的一个小错误.当 AccessToken 过期时,它会抛出一个异常,并尝试在 catch 块中使用 AcquireTokenByRefreshToken 获取一个新的.这里我们没有在 Cookie 中设置新收到的刷新令牌.我们还需要在 catch 块中添加以下语句,以便它可以获取 Refresh 令牌,然后可以将其传回以生成新的 Access Token.

We were able to resolve this. It seems to be a small mistake in the code itself. When the AccessToken expires, it throws an exception and it tries to fetch a new one using AcquireTokenByRefreshToken in the catch block. Here we were not setting the newly received refresh token back in the Cookie. We need to add below statement in the catch block also, so that it would get the Refresh token, which can then be passed back to generate a new Access Token.

httpCookie.Value = authenticationResult.RefreshToken;

这篇关于Azure - AD - AcquireTokenSilent 给出错误 failed_to_acquire_token_silently的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

相关文档推荐

How to MOQ an Indexed property(如何最小起订量索引属性)
Mocking generic methods in Moq without specifying T(在 Moq 中模拟泛型方法而不指定 T)
How Moles Isolation framework is implemented?(Moles Isolation 框架是如何实现的?)
Difference between Dependency Injection and Mocking Framework (Ninject vs RhinoMocks or Moq)(依赖注入和模拟框架之间的区别(Ninject vs RhinoMocks 或 Moq))
How to mock Controller.User using moq(如何使用 moq 模拟 Controller.User)
How do I mock a class without an interface?(如何模拟没有接口的类?)