AcquireTokenSilent 始终无法静默获取令牌
AcquireTokenSilent always Failed to acquire token silently
使用 ADAL 我有两个 AuthenticationContext
使用令牌缓存持久化在 SQL.
使用AcquireTokenByAuthorizationCode
它在数据库中写入令牌,但是当使用AcquireTokenSilent
时我总是得到
Failed to acquire token silently. Call method AcquireToken
以下是复制问题的详细信息:
我创建一个上下文
AuthenticationContext authContext = new AuthenticationContext(_authority, new AzureAdalCache(companyId, _entries, _unitOfWork));
然后我通过授权获取Token
authContext.AcquireTokenByAuthorizationCode(authorizationCode, new Uri(redirectUri), _clientCredential);
此时,它在数据库中保存了一个条目
然后如果我调用这个我得到一个异常。
authContext.AcquireTokenSilent(_authority, _clientCredential, new UserIdentifier(companyId.ToString(), UserIdentifierType.UniqueId)).AccessToken;
我也试过同样的结果:
authContext.AcquireTokenSilent(_authority, _clientId).AccessToken;
authContext.AcquireTokenSilent(_authority, _clientCredential, UserIdentifier.AnyUser).AccessToken;
我 Post 我的 AzureAdalCache
在 this Gist 中实现。
缓存的每个条目是like this。
我错过了什么?
更新
根据@vibronet 的评论回答我有这个
AuthenticationContext authContext = new AuthenticationContext(_authority, new AzureAdalCache(companyId, _entries, _unitOfWork));
authContext.AcquireTokenByAuthorizationCode(authorizationCode, new Uri(redirectUri), _clientCredential, _eWSResource);
string result = authContext.AcquireTokenSilent(_eWSResource, _clientId, UserIdentifier.AnyUser).AccessToken;
我不明白调用:
authContext.AcquireTokenSilent(
_authority,
_clientCredential,
new UserIdentifier(companyId.ToString(), UserIdentifierType.UniqueId)
).AccessToken;
UserIdentifier 必须与缓存中的值匹配,并且 CompanyID 听起来不像您为令牌取回的任何标识符。
请查看我在另一个线程上向您指出的示例,特别是在 https://github.com/AzureADSamples/WebApp-WebAPI-OpenIDConnect-DotNet/blob/master/TodoListWebApp/Controllers/TodoListController.cs
中调用 AcquireTokenSilent 时使用的标识符
您无法选择在该调用中使用哪个标识符,这取决于 AAD 发出的声明。您可以选择的唯一标识符是在缓存实例级别,而不是在单个 AcquireToken* 调用中。
问题是基本上我在我的应用程序中使用了 Common Authority https://login.windows.net/common/oauth2/authorize
。它适用于 AcquireTokenByAuthorizationCode() 但不适用于 AcquireTokenSilent()。
所以我需要它在调用 AcquireTokenByAuthorizationCode() 时保存 TenantId,并且在调用 AcquireTokenSilent() 时授权使用像 https://login.windows.net/<tenant ID>/oauth2/authorize
这样的授权。这样上面的代码就可以工作了。
我在 ASPNetCore (1.0) 中遇到了同样的问题,原因是我在登录后没有存储身份验证令牌。我通过在启动 class 中添加 OnAuthorizationCodeReceived
解决了这个问题并将我的响应类型更改为 ResponseType = OpenIdConnectResponseType.CodeIdToken
.
希望对您有所帮助。
检查缓存中是否存在令牌,否则退出并要求用户登录。
AuthenticationContext authContext = new AuthenticationContext(Startup.Authority,
new NaiveSessionCache(userObjectID));
if (authContext.TokenCache.Count == 0)
{
authContext.TokenCache.Clear();
CosmosInterface.Utils.AuthenticationHelper.token = null;
HttpContext.GetOwinContext().Authentication.SignOut(
OpenIdConnectAuthenticationDefaults.AuthenticationType,
CookieAuthenticationDefaults.AuthenticationType);
}
这是一个老问题 - 但对我来说,我需要在客户端清除我的 cookie,然后它会强制浏览器重新授权,然后一切又好了。
使用 ADAL 我有两个 AuthenticationContext
使用令牌缓存持久化在 SQL.
使用AcquireTokenByAuthorizationCode
它在数据库中写入令牌,但是当使用AcquireTokenSilent
时我总是得到
Failed to acquire token silently. Call method AcquireToken
以下是复制问题的详细信息:
我创建一个上下文
AuthenticationContext authContext = new AuthenticationContext(_authority, new AzureAdalCache(companyId, _entries, _unitOfWork));
然后我通过授权获取Token
authContext.AcquireTokenByAuthorizationCode(authorizationCode, new Uri(redirectUri), _clientCredential);
此时,它在数据库中保存了一个条目
然后如果我调用这个我得到一个异常。
authContext.AcquireTokenSilent(_authority, _clientCredential, new UserIdentifier(companyId.ToString(), UserIdentifierType.UniqueId)).AccessToken;
我也试过同样的结果:
authContext.AcquireTokenSilent(_authority, _clientId).AccessToken;
authContext.AcquireTokenSilent(_authority, _clientCredential, UserIdentifier.AnyUser).AccessToken;
我 Post 我的 AzureAdalCache
在 this Gist 中实现。
缓存的每个条目是like this。
我错过了什么?
更新
根据@vibronet 的评论回答我有这个
AuthenticationContext authContext = new AuthenticationContext(_authority, new AzureAdalCache(companyId, _entries, _unitOfWork));
authContext.AcquireTokenByAuthorizationCode(authorizationCode, new Uri(redirectUri), _clientCredential, _eWSResource);
string result = authContext.AcquireTokenSilent(_eWSResource, _clientId, UserIdentifier.AnyUser).AccessToken;
我不明白调用:
authContext.AcquireTokenSilent(
_authority,
_clientCredential,
new UserIdentifier(companyId.ToString(), UserIdentifierType.UniqueId)
).AccessToken;
UserIdentifier 必须与缓存中的值匹配,并且 CompanyID 听起来不像您为令牌取回的任何标识符。
请查看我在另一个线程上向您指出的示例,特别是在 https://github.com/AzureADSamples/WebApp-WebAPI-OpenIDConnect-DotNet/blob/master/TodoListWebApp/Controllers/TodoListController.cs
中调用 AcquireTokenSilent 时使用的标识符您无法选择在该调用中使用哪个标识符,这取决于 AAD 发出的声明。您可以选择的唯一标识符是在缓存实例级别,而不是在单个 AcquireToken* 调用中。
问题是基本上我在我的应用程序中使用了 Common Authority https://login.windows.net/common/oauth2/authorize
。它适用于 AcquireTokenByAuthorizationCode() 但不适用于 AcquireTokenSilent()。
所以我需要它在调用 AcquireTokenByAuthorizationCode() 时保存 TenantId,并且在调用 AcquireTokenSilent() 时授权使用像 https://login.windows.net/<tenant ID>/oauth2/authorize
这样的授权。这样上面的代码就可以工作了。
我在 ASPNetCore (1.0) 中遇到了同样的问题,原因是我在登录后没有存储身份验证令牌。我通过在启动 class 中添加 OnAuthorizationCodeReceived
解决了这个问题并将我的响应类型更改为 ResponseType = OpenIdConnectResponseType.CodeIdToken
.
希望对您有所帮助。
检查缓存中是否存在令牌,否则退出并要求用户登录。
AuthenticationContext authContext = new AuthenticationContext(Startup.Authority,
new NaiveSessionCache(userObjectID));
if (authContext.TokenCache.Count == 0)
{
authContext.TokenCache.Clear();
CosmosInterface.Utils.AuthenticationHelper.token = null;
HttpContext.GetOwinContext().Authentication.SignOut(
OpenIdConnectAuthenticationDefaults.AuthenticationType,
CookieAuthenticationDefaults.AuthenticationType);
}
这是一个老问题 - 但对我来说,我需要在客户端清除我的 cookie,然后它会强制浏览器重新授权,然后一切又好了。