Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/azure/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ADAL-AcquireTokenSilentAsync失败(Azure Active Directory身份验证库)_C#_Azure_Oauth 2.0_Office365_Adal - Fatal编程技术网

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

C# ADAL-AcquireTokenSilentAsync失败(Azure Active Directory身份验证库),c#,azure,oauth-2.0,office365,adal,C#,Azure,Oauth 2.0,Office365,Adal,我编写了一个新的应用程序,通过RESTAPI访问office数据,因此我想使用新的 身份验证模型(V2.0端点) 我可以通过打电话到 private static string[] scopes = { "https://outlook.office.com/mail.read", "https://outlook.office.com/calendars.read" }; public async Task<ActionResult> SignIn() {

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

我可以通过打电话到

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)
类似问题:

Microsoft已删除配置文件信息,您可以在此处阅读:

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

正确的信息在令牌\u id中

Class: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)
  };
}
我希望他们能尽快修复,我也在等待:-)

编辑:

我在这里发现了一些有趣的东西:

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

ADALV4的预发布版本不直接返回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;
}
private string GetUserEmail(AuthenticationContext,string clientId)
{
//ADAL通过客户端ID在其令牌缓存中缓存ID令牌
foreach(context.TokenCache.ReadItems()中的TokenCacheItem项)
{
if(item.Scope.Contains(clientId))
{
返回GetEmailFromIdToken(item.Token);
}
}
返回字符串。空;
}
私有字符串GetEmailFromIdToken(字符串标记)
{
//JWT由三部分组成,由“.”分隔
//第一部分是标题
//第二部分是代币
//第三部分是签名
字符串[]tokenParts=token.Split('.');
如果(长度<3)
{
//无效令牌,返回空
}
//令牌内容在urlsafe base64的第二部分中
字符串encodedToken=tokenParts[1];
//从urlsafe转换并在需要时添加填充
int leftovers=encodedToken.Length%4;
如果(剩余=2)
{
encodedToken+=“=”;
}
else if(剩余=3)
{
encodedToken+=“=”;
}
encodedToken=encodedToken.Replace('-','+').Replace('''.'和'/');
//解码字符串
var base64EncodedBytes=System.Convert.FromBase64String(encodedToken);
string decodedToken=System.Text.Encoding.UTF8.GetString(base64EncodedBytes);
//将解码后的JSON加载到动态对象中
动态jwt=Newtonsoft.Json.JsonConvert.DeserializeObject(decodedToken);
//用户的电子邮件位于首选用户名字段中
返回jwt.preferred\u用户名;
}

我还没有对此进行测试,但我会在测试后更新此帖子,或者另一个帖子会发表评论,如果他更快的话:-)

目前,我已经使用了此解决方案,但这样无法使用ADAL库的内置令牌缓存
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)
  };
}
  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;
}