尝试在 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:

Microsoft Graph permissions reference