ADAL – AcquireTokenSilentAsync失败(Azure Active Directory身份validation库)

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

v2.0 endpoit有什么不同

我可以通过电话获得令牌

private static string[] scopes = { "https://outlook.office.com/mail.read", "https://outlook.office.com/calendars.read" }; public async Task 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 SignIn() { ... SNIP var authResult = authContext.AcquireTokenSilentAsync(scopes, clientId, new UserIdentifier("contoso@foo.ch", UserIdentifierType.RequiredDisplayableId)) } 

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

感谢您的提示和想法

在此处输入图像描述

返回令牌

  { "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" } 

类似的问题: 这里

Microsoft已删除了profile_info,您可以在此处阅读: ADV2的重要更新

目前该库有一个错误,因为它仍然检查它,如果它是null,它将不会返回用户信息。

正确的信息在token_id中……

类:TokenResponse

 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开始了

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

ADAL v4的预发布版本不会直接返回ID令牌,但可以访问它。 此处包含的方法旨在解决此问题,直到更新ADAL。

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

  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; } 

我还没有对此进行测试,但是当我测试它时我会更新这篇文章,或者如果他更快的话,我会另外发表评论:-)