ConfidentialClientApplication AcquireTokenSilentAsync总是失败 [英] ConfidentialClientApplication AcquireTokenSilentAsync always fails

查看:180
本文介绍了ConfidentialClientApplication AcquireTokenSilentAsync总是失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试针对Microsoft机构使用OpenIdConnectAuthentication.我可以进行身份​​验证,但是当尝试获取访问令牌时,呼叫失败,希望我重新进行身份验证,而我却这样做.我似乎从来没有拉过适当的标记.这是获取访问令牌的代码.

I'm trying to use the OpenIdConnectAuthentication against the microsoft authority. I'm able to authenticate, but when try to obtain an access token, the call fails, wanting me to re authenticate, which I do. I seems to never pull the proper tokens. Here is the code for the obtaining the access token.

public async Task<string> GetUserAccessTokenAsync()
{
    string signedInUserID = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
    //string signedInUserID = User.Identity.GetUserId();
    tokenCache = new MSALSessionCache(
        signedInUserID,
        HttpContext.Current.GetOwinContext().Environment["System.Web.HttpContextBase"] as HttpContextBase);
    var cachedItems = tokenCache.ReadItems(appId); // see what's in the cache

    ConfidentialClientApplication cca = new ConfidentialClientApplication(
        appId,
        redirectUri,
        new ClientCredential(appSecret),
        tokenCache);

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

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

        //throw new Exception("Resource.Error_AuthChallengeNeeded");
        return null;
    }
}

我不确定我缺少什么.到目前为止,我已经使用了Microsoft Graph REST ASPNET Connect示例来指导我.我的最终目标是对用户进行身份验证,然后使用其个人资料和MS rest api中的某些项目.

I'm not sure what I am missing. I've used the Microsoft Graph REST ASPNET Connect sample to guide me so far. My end goal is to authenticate the user, and then use some items from their profile and the MS rest api.

推荐答案

我能够对此进行跟踪.因为我同时使用了Asp.net身份验证和UseOpenIdConnectAuthentication,所以必须将外部登录声明手动添加到ClaimsPrincipal.这就是我的ExternalLoginCallback(string returnUrl)的样子:

I was able to track this down. Because I was using both the Asp.net Identity auth and the UseOpenIdConnectAuthentication, I had to add the external login claims to the ClaimsPrincipal manually. This i what my ExternalLoginCallback(string returnUrl) look like:

        public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
    {
        var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
        if (loginInfo == null)
        {
            return RedirectToAction("Login");
        }

        // Sign in the user with this external login provider if the user already has a login
        var result = await SignInManager.ExternalSignInAsync(loginInfo, isPersistent: false);

        logger.Info(loginInfo.Email + " attempted an external login with a result of " + result.ToString());

        switch (result)
        {
            case SignInStatus.Success:                  
                foreach (Claim c in loginInfo.ExternalIdentity.Claims)
                {
                    SignInManager.AuthenticationManager.AuthenticationResponseGrant.Identity.AddClaim(new Claim(c.Type + "_external", c.Value));
                }

                var user = UserManager.FindById(SignInManager.AuthenticationManager.AuthenticationResponseGrant.Identity.GetUserId());

                user.LastLogin = DateTime.Now.ToUniversalTime();
                await UserManager.UpdateAsync(user);

                return RedirectToLocal(returnUrl);
            case SignInStatus.LockedOut:
                return View("Lockout");
            case SignInStatus.RequiresVerification:
                return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = false });
            case SignInStatus.Failure:
            default:
                // If the user does not have an account, then prompt the user to create an account
                ViewBag.ReturnUrl = returnUrl;
                ViewBag.LoginProvider = loginInfo.Login.LoginProvider;
                return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel { Email = loginInfo.Email });
        }
    }

因为外部标识的名称与asp.net标识匹配,所以我不得不重命名蛤the.然后,在代码中的任何地方进行调整,以寻找外部身份声明.

Because the external identity has a claim with a name that matches the asp.net identity, I had to rename the clams. Then also adjust anywhere in code looking for the external identity claims.

这篇关于ConfidentialClientApplication AcquireTokenSilentAsync总是失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆