断言不在 AspNetCore 身份验证 OpenIdConnect 的有效时间范围内
Assertion is not within its valid time range in AspNetCore Authentication OpenIdConnect
我在尝试为另一个应用程序获取令牌时开始收到此错误。
Additional information: AADSTS70002: Error validating credentials.
AADSTS50013: Assertion is not within its valid time range.
这是在我从 AspNetCore 的 1.0.1 升级到 1.1.0 后开始出现的。如果我清除我的 cookie,这个错误就会消失一段时间。
下面是我用来获取此令牌的代码。它主要改编自 GitHub.
上示例中的代码
var userObjectId = (user.FindFirst(AuthSettings.UserObjectIdClaimName))?.Value;
AuthenticationResult authResult = null;
var authContext = GetAuthContext(userObjectId);
ClientCredential credential = new ClientCredential(AuthSettings.ClientId, AuthSettings.ClientSecret);
var claimsIdentity = user.Identity as ClaimsIdentity;
var token = claimsIdentity?.BootstrapContext as string;
if (token != null)
{
try
{
authResult = await authContext.AcquireTokenAsync(appId, credential,
new UserAssertion(token)); // Error here
}
catch (Exception) { }
}
if (authResult == null)
{
// Error no token in cache here
authResult = await authContext.AcquireTokenSilentAsync(appId, credential,
new UserIdentifier(userObjectId, UserIdentifierType.UniqueId));
}
return authResult.AccessToken;
你知道有趣的是 AcquireTokenSilentAsync
如果第一次尝试失败就永远不会起作用,因为令牌缓存是空的。在我的 Startup 中,我在 OnAuthorizationCodeReceived
中有代码继续执行并将令牌存储在令牌缓存中。此回调 从未 执行。据推测,如果第一批代码不起作用,那么如果这段代码起作用,回退将处理它。
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
ClientId = authSettings.ClientId,
Authority = authSettings.Authority,
ResponseType = OpenIdConnectResponseType.IdToken,
PostLogoutRedirectUri = authSettings.PostLogoutUrl,
TokenValidationParameters = new TokenValidationParameters()
{
SaveSigninToken = true
},
Events = new OpenIdConnectEvents
{
OnRemoteFailure = authHelper.CreateOnRemoteFailureRedirectHandler("/Home/Error"),
OnAuthorizationCodeReceived =
authHelper.CreateOnAuthorizationCodeRecievedAcquireAdditionalTokenHandler(new[] { CustomerManagerApi })
},
});
这是 OnAuthorizationCodeRecieved
当前未执行的代码:
var userObjectId = (context.Ticket?.Principal?.FindFirst(AuthSettings.UserObjectIdClaimName))?.Value;
var clientCred = new ClientCredential(AuthSettings.ClientId, AuthSettings.ClientSecret);
var authContext = new AuthenticationContext(AuthSettings.Authority, TokenCacheCreator(userObjectId));
var redirectAddressForAuthCode = new Uri(context.Properties.Items[OpenIdConnectDefaults.RedirectUriForCodePropertiesKey]);
authContext.AcquireTokenByAuthorizationCodeAsync(context.ProtocolMessage.Code, redirectAddressForAuthCode, clientCred, applicationId);
context.HandleCodeRedemption();
未触发 OnAuthorizationCodeReceived
的原因是您将 ResponseType
设置为 OpenIdConnectResponseType.IdToken
,这不会向客户端发送授权码。
Additional information: AADSTS70002: Error validating credentials. AADSTS50013: Assertion is not within its valid time range.
对于此错误,请确保访问令牌未过期,然后再发送使用它进行用户断言的令牌请求。
我在交换用户断言以获取 Microsoft Graph API scope Token 时遇到了同样的问题,我发现 .Net Core Web API 允许过期令牌在过期后再保留 5 分钟,由于默认 5 分钟令牌验证时钟偏差 属性。
所以我将 TokenValidationParameters 的 ClockSkew 属性 设置为 TimeSpan.Zero,这阻止了过期的令牌请求,也解决了断言有效时间范围问题。
我在尝试为另一个应用程序获取令牌时开始收到此错误。
Additional information: AADSTS70002: Error validating credentials. AADSTS50013: Assertion is not within its valid time range.
这是在我从 AspNetCore 的 1.0.1 升级到 1.1.0 后开始出现的。如果我清除我的 cookie,这个错误就会消失一段时间。
下面是我用来获取此令牌的代码。它主要改编自 GitHub.
上示例中的代码var userObjectId = (user.FindFirst(AuthSettings.UserObjectIdClaimName))?.Value;
AuthenticationResult authResult = null;
var authContext = GetAuthContext(userObjectId);
ClientCredential credential = new ClientCredential(AuthSettings.ClientId, AuthSettings.ClientSecret);
var claimsIdentity = user.Identity as ClaimsIdentity;
var token = claimsIdentity?.BootstrapContext as string;
if (token != null)
{
try
{
authResult = await authContext.AcquireTokenAsync(appId, credential,
new UserAssertion(token)); // Error here
}
catch (Exception) { }
}
if (authResult == null)
{
// Error no token in cache here
authResult = await authContext.AcquireTokenSilentAsync(appId, credential,
new UserIdentifier(userObjectId, UserIdentifierType.UniqueId));
}
return authResult.AccessToken;
你知道有趣的是 AcquireTokenSilentAsync
如果第一次尝试失败就永远不会起作用,因为令牌缓存是空的。在我的 Startup 中,我在 OnAuthorizationCodeReceived
中有代码继续执行并将令牌存储在令牌缓存中。此回调 从未 执行。据推测,如果第一批代码不起作用,那么如果这段代码起作用,回退将处理它。
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
ClientId = authSettings.ClientId,
Authority = authSettings.Authority,
ResponseType = OpenIdConnectResponseType.IdToken,
PostLogoutRedirectUri = authSettings.PostLogoutUrl,
TokenValidationParameters = new TokenValidationParameters()
{
SaveSigninToken = true
},
Events = new OpenIdConnectEvents
{
OnRemoteFailure = authHelper.CreateOnRemoteFailureRedirectHandler("/Home/Error"),
OnAuthorizationCodeReceived =
authHelper.CreateOnAuthorizationCodeRecievedAcquireAdditionalTokenHandler(new[] { CustomerManagerApi })
},
});
这是 OnAuthorizationCodeRecieved
当前未执行的代码:
var userObjectId = (context.Ticket?.Principal?.FindFirst(AuthSettings.UserObjectIdClaimName))?.Value;
var clientCred = new ClientCredential(AuthSettings.ClientId, AuthSettings.ClientSecret);
var authContext = new AuthenticationContext(AuthSettings.Authority, TokenCacheCreator(userObjectId));
var redirectAddressForAuthCode = new Uri(context.Properties.Items[OpenIdConnectDefaults.RedirectUriForCodePropertiesKey]);
authContext.AcquireTokenByAuthorizationCodeAsync(context.ProtocolMessage.Code, redirectAddressForAuthCode, clientCred, applicationId);
context.HandleCodeRedemption();
未触发 OnAuthorizationCodeReceived
的原因是您将 ResponseType
设置为 OpenIdConnectResponseType.IdToken
,这不会向客户端发送授权码。
Additional information: AADSTS70002: Error validating credentials. AADSTS50013: Assertion is not within its valid time range.
对于此错误,请确保访问令牌未过期,然后再发送使用它进行用户断言的令牌请求。
我在交换用户断言以获取 Microsoft Graph API scope Token 时遇到了同样的问题,我发现 .Net Core Web API 允许过期令牌在过期后再保留 5 分钟,由于默认 5 分钟令牌验证时钟偏差 属性。
所以我将 TokenValidationParameters 的 ClockSkew 属性 设置为 TimeSpan.Zero,这阻止了过期的令牌请求,也解决了断言有效时间范围问题。