无法以静默方式获取令牌 - Microsoft Graph API

时间:2017-05-10 07:11:46

标签: c# asp.net-mvc token microsoft-graph

我们正在使用Microsoft Graph API开发ASP.NET MVC项目。它主要基于https://github.com/microsoftgraph/aspnet-snippets-sample的示例代码。该应用程序最初工作正常 - 我们可以使用我们的租户帐户登录并从图表中获取数据。但是,如果我们从Visual Studio开始一个新的会话,或者我们只是等待一段时间,AcquireTokenSilentAsync抛出

  

无法以静默方式获取令牌

如果网络浏览器缓存被清除,它会再次运行,但过了一会儿就会返回错误。 我们已经尝试将权限更改为普通,组织和租户,但错误仍然存​​在。

我们获取访问令牌的方法如下:

 // Gets an access token and its expiration date. First tries to get the token from the token cache.
    public async Task<string> GetUserAccessTokenAsync()
    {
        // Initialize the cache.
        HttpContextBase context = HttpContext.Current.GetOwinContext().Environment["System.Web.HttpContextBase"] as HttpContextBase;

        tokenCache = new SessionTokenCache(
            ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value,
            context);
        IEnumerable<TokenCacheItem> cachedItems = tokenCache.ReadItems(appId); // see what's in the cache
        if (cachedItems.Count() > 0)
            return cachedItems.First().Token;

        if (!redirectUri.EndsWith("/")) redirectUri = redirectUri + "/";
        string[] segments = context.Request.Path.Split(new char[] { '/' });
        ConfidentialClientApplication cca = new ConfidentialClientApplication(
            appId,
            redirectUri + segments[1],
            new ClientCredential(appSecret),
            tokenCache);

        string allScopes = nonAdminScopes;
        string[] scopes = allScopes.Split(new char[] { ' ' });
        try
        {
            AuthenticationResult result = await cca.AcquireTokenSilentAsync(scopes);
            return result.Token;
        }

        // Unable to retrieve the access token silently.
        catch (MsalSilentTokenAcquisitionException)
        {
            HttpContext.Current.Request.GetOwinContext().Authentication.Challenge(
              new AuthenticationProperties() { RedirectUri = redirectUri + segments[1] },
              OpenIdConnectAuthenticationDefaults.AuthenticationType);

            throw new ServiceException(
                new Error
                {
                    Code = GraphErrorCode.AuthenticationFailure.ToString(),
                    Message = Resource.Error_AuthChallengeNeeded,
                });
        }
    }

为什么不能无声地获得令牌的任何想法?

1 个答案:

答案 0 :(得分:1)

你如何处理抛出的异常?在您提供的示例中,他们使用try / catch处理错误,如果引发异常并且错误消息匹配,则返回空结果。此请求将被OpenId中间件拦截(因为..GetOwinContext()。Authentication.Challenge()将响应代码设置为401,将身份验证类型设置为OpenIdConnectAuthenticationDefaults.AuthenticationType)。

        try
        {

            // Initialize the GraphServiceClient.
            GraphServiceClient graphClient = SDKHelper.GetAuthenticatedClient();

            // Get the files and folders in the current user's drive.
            results.Items = await filesService.GetMyFilesAndFolders(graphClient);
        }
        catch (ServiceException se)
        {
            if (se.Error.Message == Resource.Error_AuthChallengeNeeded) return new EmptyResult();
            return RedirectToAction("Index", "Error", new { message = string.Format(Resource.Error_Message, Request.RawUrl, se.Error.Code, se.Error.Message) });
        }