.net - 尝试在 Azure Publish 上验证图形客户端时出现异常 : "Failed to acquire token silently. Call method AcquireToken"

标签 .net azure azure-active-directory microsoft-graph-api adal

我尝试使用 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 Xu,我已将代码更新为以下内容:

    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);
        }
        ));
    }

以下是输出,因此我认为它现在已成功返回 token :

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 的 User 属性没有获取任何数据。

最佳答案

AcquireTokenSilentAsync 方法尝试从缓存获取 token 或使用刷新 token 刷新访问 token 。

如果您正在开发服务,可以考虑使用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。详细权限可以引用以下链接:

Microsoft Graph permissions reference

关于.net - 尝试在 Azure Publish 上验证图形客户端时出现异常 : "Failed to acquire token silently. Call method AcquireToken",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44643018/

相关文章:

c# - 为什么不能将 List<Derived> 分配给 List<Base>?

azure - 为什么 Azure 应用程序网关需要空子网

.net - Azure WebJob 存储连接

azure - 如何根据队列长度扩展 worker 角色

Azure AD SCIM 客户端实现 - 用户/组说明

c# - 如何使用 C# 针对 Azure AD 验证用户密码

azure - 无法使用服务主体创建 AD 应用程序

c# - 在 Entity Framework 6.1 中使用 SQLite 1.0.92 时遇到问题

c# - 在 asp.net WebService 中未调用 Application_End 时

c# - 客户端配置文件错误