我编写了一个新的应用程序来通过其余的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,但此信息不存储在令牌对象中。令牌的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"
}
类似的问题: Here
答案 0 :(得分:3)
Microsoft已删除profile_info,您可以在此处阅读: Important Updates to 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 get started
正如我已经说过的,存储在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;
}
我还没有测试过这个,但是当我测试它时我会更新这篇文章,或者如果他更快的话,我会另外发表评论: - )