编程语言
首页 > 编程语言> > c#-ADAL-AcquireTokenSilentAsync失败(Azure Active Directory身份验证库)

c#-ADAL-AcquireTokenSilentAsync失败(Azure Active Directory身份验证库)

作者:互联网

我编写了一个新应用程序以通过其余API访问办公室数据,因此我想使用新的
身份验证模型(V2.0端点)

What’s different about the v2.0 endpoit

我可以致电获得令牌

private static string[] scopes = { "https://outlook.office.com/mail.read", "https://outlook.office.com/calendars.read" };
    public async Task<ActionResult> SignIn()
    {
     ... SNIP
      Uri authUri = await authContext.GetAuthorizationRequestUrlAsync(scopes, null, clientId, redirectUri, new UserIdentifier("contoso@foo", UserIdentifierType.RequiredDisplayableId), null);        
      return Redirect(authUri.ToString());
    }
authContext.AcquireTokenByAuthorizationCodeAsync(authCode, redirectUri, credential, scopes)

问题是第二次致电

    public async Task<ActionResult> SignIn()
    {
     ... SNIP
     var authResult = authContext.AcquireTokenSilentAsync(scopes, clientId, new UserIdentifier("contoso@foo.ch", UserIdentifierType.RequiredDisplayableId))
    }

返回的令牌确实包含UniqueId,但是此信息未存储在Token对象中.令牌的UserInfo始终为null.由于此字段为空,因此令牌缓存无法找到令牌.

谢谢您的提示和想法

enter image description here

返回的令牌

   {  
   "aud":"https://outlook.office.com",
   "iss":"https://sts.windows.net/f2ac6f3f-3df0-4068-a677-e4dfdf924b2/",
   "iat":146   dfdf21,
   "nbf":146   dfdf4621,
   "exp":1463   dfdf38521,
   "acr":"1",
   "amr":[  
      "pwd"
   ],
   "appid":"b13dfdf9-0561-4dfdff5-945c-778dfdf0de5cd",
   "appidacr":"1",
   "family_name":"Pan",
   "given_name":"Peter",
   "ipaddr":"12.12.12.17",
   "name":"Peter Pan",
   "oid":"4b83dfdfdb-f6db-433e-b70a-2f9a6dbbeb48",
   "puid":"100dfdfdfF5FBC",
   "scp":"Calendars.Read Mail.Read Mail.ReadWrite",
   "sub":"Z-chdfdsfnWqduUkCGZpsIdp-fdhpMMqqtwcHGs",
   "tid":"f2ac6f3f-3560-4068-a677-e4bfe0c924b2",
   "unique_name":"foo@contoso",
   "upn":"foo@contoso",
   "ver":"1.0"
}

类似的问题:
Here

解决方法:

Microsoft已删除profile_info,您可以在此处阅读:
Important Updates to ADV2

目前该库存在一个错误,因为它仍在检查它,并且如果它为null,则不会返回用户信息.

正确的信息在token_id中…

类:令牌响应

private AuthenticationResultEx GetResult(string token, string scope, long expiresIn)
{
  DateTimeOffset expiresOn = (DateTimeOffset) (DateTime.UtcNow + TimeSpan.FromSeconds((double) expiresIn));
  AuthenticationResult authenticationResult = new AuthenticationResult(this.TokenType, token, expiresOn);
  ProfileInfo profileInfo = ProfileInfo.Parse(this.ProfileInfoString);
  if (profileInfo != null)
  {
    string tenantId = profileInfo.TenantId;
    string str1 = (string) null;
    string str2 = (string) null;
    if (!string.IsNullOrWhiteSpace(profileInfo.Subject))
      str1 = profileInfo.Subject;
    if (!string.IsNullOrWhiteSpace(profileInfo.PreferredUsername))
      str2 = profileInfo.PreferredUsername;
    authenticationResult.UpdateTenantAndUserInfo(tenantId, this.ProfileInfoString, new UserInfo()
    {
      UniqueId = str1,
      DisplayableId = str2,
      Name = profileInfo.Name,
      Version = profileInfo.Version
    });
  }
  return new AuthenticationResultEx()
  {
    Result = authenticationResult,
    RefreshToken = this.RefreshToken,
    ScopeInResponse = AdalStringHelper.CreateArrayFromSingleString(scope)
  };
}

我希望他们能尽快修复它,我也在等待:-)

编辑:

我在这里发现了一些有趣的东西:
Dev Outlook get started

正如我已经说过的,在上面的链接中存储在token_id中的所有信息可以阅读:

The prerelease version of ADAL v4 doesn’t return the ID token directly, but it is accessible. The method included here is intended to work around this issue until ADAL is updated.

他们解释了一种访问令牌的方法:

  private string GetUserEmail(AuthenticationContext context, string clientId)
{
    // ADAL caches the ID token in its token cache by the client ID
    foreach (TokenCacheItem item in context.TokenCache.ReadItems())
    {
        if (item.Scope.Contains(clientId))
        {
            return GetEmailFromIdToken(item.Token);
        }
    }
    return string.Empty;
}

    private string GetEmailFromIdToken(string token)
{
    // JWT is made of three parts, separated by a '.' 
    // First part is the header 
    // Second part is the token 
    // Third part is the signature 
    string[] tokenParts = token.Split('.');
    if (tokenParts.Length < 3)
    {
        // Invalid token, return empty
    }
    // Token content is in the second part, in urlsafe base64
    string encodedToken = tokenParts[1];
    // Convert from urlsafe and add padding if needed
    int leftovers = encodedToken.Length % 4;
    if (leftovers == 2)
    {
        encodedToken += "==";
    }
    else if (leftovers == 3)
    {
        encodedToken += "=";
    }
    encodedToken = encodedToken.Replace('-', '+').Replace('_', '/');
    // Decode the string
    var base64EncodedBytes = System.Convert.FromBase64String(encodedToken);
    string decodedToken = System.Text.Encoding.UTF8.GetString(base64EncodedBytes);
    // Load the decoded JSON into a dynamic object
    dynamic jwt = Newtonsoft.Json.JsonConvert.DeserializeObject(decodedToken);
    // User's email is in the preferred_username field
    return jwt.preferred_username;
}

我尚未对此进行测试,但是我将在对其进行测试后对其进行更新,或者如果他的速度更快,请另外发表评论:-)

标签:adal,azure,oauth-2-0,office365,c
来源: https://codeday.me/bug/20191118/2029878.html