我有一个在 azure 上运行的 .NET MVC Core 3.1 Webapp。此 Web 应用程序使用针对 Azure AD 的 SSO,并在委托模式下使用 powerbi API 和图形 API。
一切正常,但现在我经常在触发 AcquireTokenSilentAsync 时遇到 failed_to_acquire_token_silently 异常。这不是 100% 的时间,而且对我来说有点随机。
让我尝试提取我认为最相关的代码部分。
Startup.cs / 配置服务:
services.AddAuthentication("Azures").AddPolicyScheme("Azures", "Authorize AzureAd or AzureAdBearer", options =>
{
options.ForwardDefaultSelector = context =>
{
....
};
})
.AddJwtBearer(x =>
{
.....
})
// For browser access
.AddAzureAD(options => Configuration.Bind("AzureAd", options));
Startup.cs / ConfigureTokenHandling:
private void ConfigureTokenHandling(IServiceCollection services)
{
if (Configuration["AuthWithAppSecret:ClientSecret"] != "")
{
services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
{
options.ResponseType = Configuration["AuthWithAppSecret:ResponseType"];
options.ClientSecret = Configuration["AuthWithAppSecret:ClientSecret"];
options.Events = new OpenIdConnectEvents
{
OnAuthorizationCodeReceived = async ctx =>
{
HttpRequest request = ctx.HttpContext.Request;
//We need to also specify the redirect URL used
string currentUri = UriHelper.BuildAbsolute(request.Scheme, request.Host, request.PathBase, request.Path);
//Credentials for app itself
var credential = new ClientCredential(ctx.Options.ClientId, ctx.Options.ClientSecret);
//Construct token cache
ITokenCacheFactory cacheFactory = ctx.HttpContext.RequestServices.GetRequiredService<ITokenCacheFactory>();
TokenCache cache = cacheFactory.CreateForUser(ctx.Principal);
var authContext = new AuthenticationContext(ctx.Options.Authority, cache);
string resource = Configuration["PowerBI:PowerBiResourceUrl"];
AuthenticationResult result = await authContext.AcquireTokenByAuthorizationCodeAsync(
ctx.ProtocolMessage.Code, new Uri(currentUri), credential, resource);
//Tell the OIDC middleware we got the tokens, it doesn't need to do anything
ctx.HandleCodeRedemption(result.AccessToken, result.IdToken);
}
};
});
}
}
控制器是这样的:
public class ProjectsController : BaseController
{
private readonly ITokenCacheFactory _tokenCacheFactory;
public ProjectsController(MyContext context, IConfiguration configuration, ITokenCacheFactory tokenCacheFactory)
{
_context = context;
_tokenCacheFactory = tokenCacheFactory;
_configuration = configuration;
}
后来由控制器触发:
static public async Task<string> GetAccessTokenAsync2(IConfiguration _configuration, ITokenCacheFactory _tokenCacheFactory, ClaimsPrincipal User, string resURL, Uri redirectURI)
{
string authority = _configuration["AzureAd:Authority"];
string clientId = _configuration["AzureAd:ClientId"];
string clientSecret = _configuration["AuthWithAppSecret:ClientSecret"];
var cache = _tokenCacheFactory.CreateForUser(User);
var authContext = new AuthenticationContext(authority, cache);
var credential = new ClientCredential(clientId, clientSecret);
var userId = User.GetObjectId();
AuthenticationResult result;
try
{
result = await authContext.AcquireTokenSilentAsync(
resURL,
credential,
new UserIdentifier(userId, UserIdentifierType.UniqueId));
}
catch (AdalException ex)
{
mylog.Info("GetAccessTokenAsync - Adal Ex:" + ex.ErrorCode);
if (ex.ErrorCode == "failed_to_acquire_token_silently")
{
// There are no tokens in the cache.
try
{
PlatformParameters param = new PlatformParameters();
result = await authContext.AcquireTokenAsync(resURL, clientId, redirectURI, param, new UserIdentifier(userId, UserIdentifierType.UniqueId));
}
catch (Exception e)
{
mylog.Error("GetAccessTokenAsync - AcquireTokenAsync" + e.ToString());
throw e;
}
}
else
throw ex;
}
return result.AccessToken;
}
添加了 AcquireTokenAsync 以扭转 failed_to_acquire_token_silently 问题(但它完全失败了)。
你知道为什么它不时失败吗?任何其他想法如何解决它?
谢谢!!!基督教
编辑 07/04: 这里有一个例子:
2021-04-07 15:18:24.674 +00:00 OnAuthorizationCodeReceived is triggered for user fd918ddf-fbb9-40d2-812b-b01876118f42
2021-04-07 15:18:31.675 +00:00 AcquireTokenSilentAsync - trigger exception userId 'fd918ddf-fbb9-40d2-812b-b01876118f42'
用户已正确针对 AD 进行身份验证。收到一个代码,几秒钟后出现 failed_to_acquire_token_silently 异常。