C# 机密客户端应用程序AcquireTokenSilentAsync始终失败

C# 机密客户端应用程序AcquireTokenSilentAsync始终失败,c#,asp.net-mvc,authentication,C#,Asp.net Mvc,Authentication,我正在尝试对microsoft授权使用OpenIdConnectAuthentication。我可以进行身份验证,但当尝试获取访问令牌时,调用失败,需要我重新进行身份验证,我会这样做。我似乎从来没有拿过合适的代币。以下是获取访问令牌的代码 public async Task<string> GetUserAccessTokenAsync() { string signedInUserID = ClaimsPrincipal.Current.FindFirst(ClaimTyp

我正在尝试对microsoft授权使用OpenIdConnectAuthentication。我可以进行身份验证,但当尝试获取访问令牌时,调用失败,需要我重新进行身份验证,我会这样做。我似乎从来没有拿过合适的代币。以下是获取访问令牌的代码

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;
    }
}
公共异步任务GetUserAccessTokenAsync() { 字符串signedInUserID=ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value; //字符串signedInUserID=User.Identity.GetUserId(); tokenCache=新的MSALSessionCache( 签名用户ID, HttpContext.Current.GetOwinContext().Environment[“System.Web.HttpContextBase”]作为HttpContextBase); var cachedItems=tokenCache.ReadItems(appId);//查看缓存中的内容 机密客户端应用程序cca=新的机密客户端应用程序( 阿皮德, 乌里, 新客户端凭据(appSecret), 令牌缓存); 尝试 { AuthenticationResult=等待cca.AcquireTokenSilentAsync(scopes.Split(新字符[]{''})); 返回result.Token; } //无法以静默方式检索访问令牌。 捕获(MsalSilentTokenAcquisitionException) { HttpContext.Current.Request.GetOwinContext().Authentication.Challenge( 新建AuthenticationProperties(){RedirectUri=“/”}, OpenIdConnectAuthenticationDefaults.AuthenticationType); //抛出新异常(“Resource.Error_authChallengeEded”); 返回null; } }
我不确定我错过了什么。到目前为止,我使用了Microsoft Graph REST ASPNET Connect示例来指导我。我的最终目标是对用户进行身份验证,然后使用他们的配置文件和MS rest api中的一些项目。

我能够找到这一点。因为我同时使用Asp.net身份验证和UseOpenIdConnectAuthentication,所以我必须手动将外部登录声明添加到ClaimsPrincipal。这是我的ExternalLoginCallback(字符串返回URL)的外观:

        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 });
        }
    }
public异步任务ExternalLoginCallback(string returnUrl)
{
var loginInfo=await AuthenticationManager.GetExternalLoginInfoAsync();
if(loginInfo==null)
{
返回重定向操作(“登录”);
}
//如果用户已经登录,请使用此外部登录提供程序登录该用户
var result=await SignInManager.ExternalSignInAsync(loginInfo,isPersistent:false);
logger.Info(loginInfo.Email+“尝试外部登录,结果为”+result.ToString());
开关(结果)
{
案例标志状态成功:
foreach(loginInfo.ExternalIdentity.Claims中的索赔c)
{
SignInManager.AuthenticationManager.AuthenticationResponseGrant.Identity.AddClaim(新声明(c.Type+“_external”,c.Value));
}
var user=UserManager.FindById(SignInManager.AuthenticationManager.AuthenticationResponseGrant.Identity.GetUserId());
user.LastLogin=DateTime.Now.ToUniversalTime();
等待UserManager.UpdateAsync(用户);
返回重定向到本地(returnUrl);
案例标志状态锁定输出:
返回视图(“锁定”);
案例标志状态。要求验证:
return RedirectToAction(“SendCode”,new{ReturnUrl=ReturnUrl,RememberMe=false});
案例信号状态故障:
违约:
//如果用户没有帐户,则提示用户创建帐户
ViewBag.ReturnUrl=返回URL;
ViewBag.LoginProvider=loginInfo.Login.LoginProvider;
返回视图(“ExternalLoginConfirmation”,新的ExternalLoginConfirmationViewModel{Email=loginInfo.Email});
}
}
因为外部标识有一个名称与asp.net标识匹配的声明,所以我不得不重命名Clam。然后还要调整代码中的任意位置,以查找外部标识声明