[英]ADB2C - Handling the "Null user was passed in AcquiretokenSilent API" error when token cache expires
我已经设法将我的应用程序配置为使用 ADB2C 进行身份验证,并且它似乎工作正常。 实现的 ADB2C 代码是对 Microsoft 示例之一的调整,其中他们使用 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();
返回空值。 这可能是因为令牌缓存在应用程序重启时被破坏,所以我可能可以使用 Redis 缓存来修复。
然而,我的主要问题是如何处理拥有空帐户但同时被“验证”的情况。 即使我的帐户为空,我对网站的请求如何得到验证? 例如,它不应该失败并将我重定向到登录页面吗?
我尝试查看授权过滤器,并使用以下代码连接到身份验证过程并验证用户是否为空,但无济于事。 永远不会调用以下事件(这是在 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;
}
}
});
对我来说,这一切都太抽象了,无法理解正在发生的事情。 要么如此,要么我错过了一些基本的东西。
注意:如果我尝试将空帐户传递给 secretClientApplication.AcquireTokenSilentAsync confidentialClientApplication.AcquireTokenSilentAsync()
方法,则会抛出错误“空用户已在 AcquiretokenSilent API 中传递。传入用户对象或调用acquireToken 验证。 ”。
我用这个代码解决了:
protected override void OnException(ExceptionContext filterContext)
{
if (filterContext.Exception is Microsoft.Identity.Client.MsalUiRequiredException)
{
RedirectToAction("SignIn", "Account");
}
else {
//Do your logging
// ...
}
}
我会寻找更好的解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.