尝试在 Azure Publish 上验证 Graph 客户端时出现异常:"Failed to acquire token silently. Call method AcquireToken"
Exception trying to Authenticate Graph Client on Azure Publish: "Failed to acquire token silently. Call method AcquireToken"
我正在尝试使用 ADAL 对 Microsoft Graph API 进行身份验证,但在发布到 Azure 时出现以下异常:
"Failed to acquire token silently. Call method AcquireToken"
当我在本地 运行 时它工作正常。
public GraphServiceClient GetAuthGraphClient()
{
string graphResourceID = "https://graph.microsoft.com/";
return new GraphServiceClient(
new DelegateAuthenticationProvider(async (requestMessage) =>
{
string accessToken = await GetTokenForApplication(graphResourceID);
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", accessToken);
}
));
}
public async Task<string> GetTokenForApplication(string graphResourceID)
{
string signedInUserID = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
string tenantID = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;
string userObjectID = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
try {
// get a token for the Graph without triggering any user interaction (from the cache, via multi-resource refresh token, etc)
ClientCredential clientcred = new ClientCredential(clientId, appKey);
// initialize AuthenticationContext with the token cache of the currently signed in user, as kept in the app's database
AuthenticationContext authenticationContext = new AuthenticationContext(aadInstance + tenantID, new ADALTokenCache(signedInUserID));
AuthenticationResult authenticationResult = await authenticationContext.AcquireTokenSilentAsync(graphResourceID, clientcred, UserIdentifier.AnyUser);
return authenticationResult.AccessToken;
}
catch (Exception e)
{
// Capture error for handling outside of catch block
ErrorMessage = e.Message;
return null;
}
}
更新
根据@Fei Xue,我已将我的代码更新为以下内容:
public string GetTokenForApplication(string graphResourceID)
{
string signedInUserID = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
string tenantID = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;
string userObjectID = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
string authority = "https://login.microsoftonline.com/" + tenantID;
try {
// get a token for the Graph without triggering any user interaction (from the cache, via multi-resource refresh token, etc)
ClientCredential clientcred = new ClientCredential(clientId, appKey);
// initialize AuthenticationContext with the token cache of the currently signed in user, as kept in the app's database
AuthenticationContext authenticationContext = new AuthenticationContext(authority);
var token = authenticationContext.AcquireTokenAsync(graphResourceID, clientcred).Result.AccessToken;
return token;
}
catch (Exception e)
{
ErrorMessage = e.Message;
return null;
}
}
public GraphServiceClient GetAuthGraphClient()
{
string graphResourceID = "https://graph.microsoft.com/";
return new GraphServiceClient(
new DelegateAuthenticationProvider((requestMessage) =>
{
string accessToken = GetTokenForApplication(graphResourceID);
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", accessToken);
return Task.FromResult(0);
}
));
}
以下是输出,所以我认为它现在已成功返回令牌:
iisexpress.exe Information: 0 : 6/20/2017 12:23:36 PM: 29c5558f-e33b-4312-b235-612909ac1309 - AcquireTokenHandlerBase: === Token Acquisition finished successfully. An access token was retuned:
Access Token Hash: <a long access token>
Refresh Token Hash: [No Refresh Token]
Expiration Time: 6/20/2017 1:23:34 PM +00:00
User Hash: null
但是,现在,我认为我没有正确获取用户配置文件。这是正确的吗?
public void GetUserProfile(GraphServiceClient graphClient)
{
this.User = Task.Run(async () => { return await graphClient.Me.Request().GetAsync(); }).Result;
}
因为我的 Viewmodel 的用户 属性 没有获取任何数据。
AcquireTokenSilentAsync
方法尝试从缓存获取令牌或使用刷新令牌刷新访问令牌。
如果您正在开发一项服务,您可以考虑使用 client credentials flow 通过 Azure AD 进行身份验证。这是供您参考的代码:
string authority = "https://login.microsoftonline.com/{tenant}";
string clientId = "";
string secret = "";
string resource = "https://graph.microsoft.com/";
var credential = new ClientCredential(clientId, secret);
AuthenticationContext authContext = new AuthenticationContext(authority);
var token = authContext.AcquireTokenAsync(resource, credential).Result.AccessToken;
此外,请确保您有足够的权限来调用相应的 Microsoft Graph REST。详细的权限可以参考下面的link:
我正在尝试使用 ADAL 对 Microsoft Graph API 进行身份验证,但在发布到 Azure 时出现以下异常:
"Failed to acquire token silently. Call method AcquireToken"
当我在本地 运行 时它工作正常。
public GraphServiceClient GetAuthGraphClient()
{
string graphResourceID = "https://graph.microsoft.com/";
return new GraphServiceClient(
new DelegateAuthenticationProvider(async (requestMessage) =>
{
string accessToken = await GetTokenForApplication(graphResourceID);
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", accessToken);
}
));
}
public async Task<string> GetTokenForApplication(string graphResourceID)
{
string signedInUserID = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
string tenantID = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;
string userObjectID = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
try {
// get a token for the Graph without triggering any user interaction (from the cache, via multi-resource refresh token, etc)
ClientCredential clientcred = new ClientCredential(clientId, appKey);
// initialize AuthenticationContext with the token cache of the currently signed in user, as kept in the app's database
AuthenticationContext authenticationContext = new AuthenticationContext(aadInstance + tenantID, new ADALTokenCache(signedInUserID));
AuthenticationResult authenticationResult = await authenticationContext.AcquireTokenSilentAsync(graphResourceID, clientcred, UserIdentifier.AnyUser);
return authenticationResult.AccessToken;
}
catch (Exception e)
{
// Capture error for handling outside of catch block
ErrorMessage = e.Message;
return null;
}
}
更新 根据@Fei Xue,我已将我的代码更新为以下内容:
public string GetTokenForApplication(string graphResourceID)
{
string signedInUserID = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
string tenantID = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;
string userObjectID = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
string authority = "https://login.microsoftonline.com/" + tenantID;
try {
// get a token for the Graph without triggering any user interaction (from the cache, via multi-resource refresh token, etc)
ClientCredential clientcred = new ClientCredential(clientId, appKey);
// initialize AuthenticationContext with the token cache of the currently signed in user, as kept in the app's database
AuthenticationContext authenticationContext = new AuthenticationContext(authority);
var token = authenticationContext.AcquireTokenAsync(graphResourceID, clientcred).Result.AccessToken;
return token;
}
catch (Exception e)
{
ErrorMessage = e.Message;
return null;
}
}
public GraphServiceClient GetAuthGraphClient()
{
string graphResourceID = "https://graph.microsoft.com/";
return new GraphServiceClient(
new DelegateAuthenticationProvider((requestMessage) =>
{
string accessToken = GetTokenForApplication(graphResourceID);
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", accessToken);
return Task.FromResult(0);
}
));
}
以下是输出,所以我认为它现在已成功返回令牌:
iisexpress.exe Information: 0 : 6/20/2017 12:23:36 PM: 29c5558f-e33b-4312-b235-612909ac1309 - AcquireTokenHandlerBase: === Token Acquisition finished successfully. An access token was retuned:
Access Token Hash: <a long access token>
Refresh Token Hash: [No Refresh Token]
Expiration Time: 6/20/2017 1:23:34 PM +00:00
User Hash: null
但是,现在,我认为我没有正确获取用户配置文件。这是正确的吗?
public void GetUserProfile(GraphServiceClient graphClient)
{
this.User = Task.Run(async () => { return await graphClient.Me.Request().GetAsync(); }).Result;
}
因为我的 Viewmodel 的用户 属性 没有获取任何数据。
AcquireTokenSilentAsync
方法尝试从缓存获取令牌或使用刷新令牌刷新访问令牌。
如果您正在开发一项服务,您可以考虑使用 client credentials flow 通过 Azure AD 进行身份验证。这是供您参考的代码:
string authority = "https://login.microsoftonline.com/{tenant}";
string clientId = "";
string secret = "";
string resource = "https://graph.microsoft.com/";
var credential = new ClientCredential(clientId, secret);
AuthenticationContext authContext = new AuthenticationContext(authority);
var token = authContext.AcquireTokenAsync(resource, credential).Result.AccessToken;
此外,请确保您有足够的权限来调用相应的 Microsoft Graph REST。详细的权限可以参考下面的link: