C# 机密客户端应用程序AcquireTokenSilentAsync始终失败
我正在尝试对microsoft授权使用OpenIdConnectAuthentication。我可以进行身份验证,但当尝试获取访问令牌时,调用失败,需要我重新进行身份验证,我会这样做。我似乎从来没有拿过合适的代币。以下是获取访问令牌的代码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
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。然后还要调整代码中的任意位置,以查找外部标识声明