ADB2C - 处理令牌缓存过期时的"Null user was passed in AcquiretokenSilent API"错误



我已经成功地将我的应用程序配置为使用ADB2C进行身份验证,而且它似乎工作得很好。实现的ADB2C代码是对微软的一个示例的调整,在该示例中,他们使用SessionTokenCache类来管理TokenCache的实例。在我的应用程序中,我检索访问令牌如下:

private async Task<string> _getAccessToken(IConfidentialClientCredentials credentials)
{
if (this.HasCredentials())
{
var clientCredential = new ClientCredential(credentials.ClientSecret);
var userId = this._getUserIdClaimValue();
var tokenCache = new SessionTokenCache(_httpContextResolver.Context, userId);                
var confidentialClientApplication = new ConfidentialClientApplication(
credentials.ClientId,
credentials.Authority,
credentials.RedirectUri,
clientCredential,
tokenCache.GetInstance(),
null);
IAccount account = confidentialClientApplication.GetAccountsAsync().Result.FirstOrDefault();
if (account == null)
{
return "";
}
var authenticationResult = await confidentialClientApplication.AcquireTokenSilentAsync(
credentials.ApiScopes.Split(' '),
account,
credentials.Authority,
false);
return authenticationResult.AccessToken;
}
else
{
return "";
}
}

此方法用于获取访问令牌,并将其传递到HttpClient的请求标头中,如下所示:

...
using (var request = new HttpRequestMessage(HttpMethod.Get, address.AbsoluteUri))
{
if (this.HasCredentials())
{
string accessToken = await this._getAccessToken(_confidentialClientCredentials);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
}
using (HttpResponseMessage response = await this.SendAsync(request))
{
//result-processing logic
}
...

问题是,当应用程序重新启动时,用户仍然通过ADB2C cookie进行身份验证,但confidentialClientApplication.GetAccountsAsync().Result.FirstOrDefault();返回null。发生这种情况可能是因为令牌缓存在应用程序重新启动时被破坏,所以我可能可以使用Redis缓存来修复。

然而,我的主要问题是如何处理帐户为空但同时被"验证"的情况。即使我有一个空帐户,我对网站的请求是如何通过身份验证的?例如,它不应该失败并将我重定向到登录页面吗?

我尝试查看Authorization过滤器,并使用以下代码连接到auth进程并验证user是否为null,但没有成功。以下事件从未被调用(这是在ConfigureServices中):

services.AddAuthentication(AzureADB2CDefaults.AuthenticationScheme)            
.AddAzureADB2C(options => Configuration.Bind("ActiveDirectoryB2C", options))
.AddAzureADB2CBearer(options => Configuration.Bind("ActiveDirectoryB2C", options))
.AddCookie((options) => new CookieAuthenticationOptions
{
Events = new CookieAuthenticationEvents
{
OnValidatePrincipal = context =>
{
// context.Principal gives you access to the logged-in user
// context.Properties.GetTokens() gives you access to all the tokens
return Task.CompletedTask;
},
OnSignedIn = context =>
{
return Task.CompletedTask;
}
}
});

这一切让我觉得有点过于抽象,无法理解发生了什么。要么是这样,要么我错过了一些基本的东西。

注意:如果我试图将空帐户传递给confidentialClientApplication.AcquireTokenSilentAsync()方法,将抛出错误">在AcquiretokenSilent API中传递了Null用户。传入用户对象或调用acquireToken authenticate。"。

我用这个代码解决了问题:

protected override void OnException(ExceptionContext filterContext)
{
if (filterContext.Exception is Microsoft.Identity.Client.MsalUiRequiredException)
{
RedirectToAction("SignIn", "Account");
}
else {
//Do your logging
// ...
}
}

我会寻找更好的解决方案。

相关内容

最新更新