【问题标题】:Validating OpenId IdToken On Each Request在每个请求上验证 OpenId IdToken
【发布时间】:2018-05-19 08:58:30
【问题描述】:

我正在尝试验证我在每个请求中从 Azure AD 获得的 IdToken,但我不断收到错误消息,提示令牌上没有签名。当我验证访问令牌时它可以工作,但我宁愿使用包含用户声明的 Id 令牌。有没有办法让Azure也发回带有签名的Id Token?

public JwtSecurityToken ValidateJwtToken(string jwtToken)
    {
        string stsDiscoveryEndpoint = $"{_authority}/.well-known/openid-configuration";

       ConfigurationManager<OpenIdConnectConfiguration> configManager =
            new ConfigurationManager<OpenIdConnectConfiguration>(stsDiscoveryEndpoint, new OpenIdConnectConfigurationRetriever());

       OpenIdConnectConfiguration config = configManager.GetConfigurationAsync().Result;

       TokenValidationParameters validationParameters = new TokenValidationParameters
        {
            ValidateAudience = false,
            ValidateIssuer = false,
            ValidateLifetime = false,
            IssuerSigningKeys = config.SigningKeys
        };

       JwtSecurityTokenHandler tokendHandler = new JwtSecurityTokenHandler();

       try
        {
            SecurityToken token;
            tokendHandler.ValidateToken(jwtToken, validationParameters, out token);

           return token as JwtSecurityToken;
        }
        catch (Exception ex)
        {
            loggingService.LogError("Could not validate azure ad token", nameof(AzureSecurityService), ex);
            return null;
        }
    }

   public async Task<string> GenerateToken(string code)
    {
        AuthenticationContext authenticationContext = new AuthenticationContext(_authority);

       try
        {
            string baseUrl = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority);
            AuthenticationResult result =
                await authenticationContext.AcquireTokenByAuthorizationCodeAsync(code, new Uri(baseUrl), new ClientCredential(_clientId, _clientSecret));

           return result.IdToken;
        }
        catch (AdalException adalex)
        {
            loggingService.LogError("Could not get authorization request url", nameof(AzureSecurityService), adalex);
            return null;
        }
        catch (Exception ex)
        {
            loggingService.LogError("Could not get authorization request url", nameof(AzureSecurityService), ex);
            return null;
        }
    }

   public async Task<string> GetAuthUrl()
    {
        AuthenticationContext authenticationContext = new AuthenticationContext(_authority);

       // Config for OAuth client credentials  
       try
        {
            string baseUrl = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority);
            var authUri =
                await authenticationContext.GetAuthorizationRequestUrlAsync("00000000-0000-0000-0000-000000000000", _clientId, new Uri(baseUrl), UserIdentifier.AnyUser, null);

           return authUri.ToString();
        }
        catch (AdalException adalex)
        {
            loggingService.LogError("Could not get authorization request url", nameof(AzureSecurityService), adalex);
            return null;
        }
        catch (Exception ex)
        {
            loggingService.LogError("Could not get authorization request url", nameof(AzureSecurityService), ex);
            return null;
        }
    }

更新

因此,无论出于何种原因,即使没有提供范围,我还是要收回索赔。我现在所做的只是将查询参数添加到 auth url 以获取范围并请求 openid 和配置文件:

var authUri =
                await authenticationContext.GetAuthorizationRequestUrlAsync("00000000-0000-0000-0000-000000000000", _clientId, new Uri(GetBaseUrl()), UserIdentifier.AnyUser, "scope=openid profile");

我现在的问题是为什么默认范围不返回带有签名的 id_token?

【问题讨论】:

  • 您是否尝试过查看文档?可能他们可能会提到这种行为
  • 我已经翻阅了文档...没有看到任何提及缺少签名的内容..
  • 您的授权请求中是否有范围值 openid ?事实上,Azure OAuth 2.0 令牌响应包含一个未签名的 id 令牌 JWT
  • 我最初发布这个问题时没有,现在只是想知道为什么如果我不将该值放入令牌未签名的请求中..

标签: c# azure azure-active-directory openid openid-connect


【解决方案1】:

您应该忘记在您的授权请求中输入所需的范围值,

来自OpenID Connect specification

范围

必填。 OpenID Connect 请求必须包含 openid 范围值。 如果 openid 范围值不存在,则行为完全是 未指定。可能存在其他范围值。使用的范围值 不被实现理解的应该被忽略。看 第 5.4 节和第 11 节中定义的附加范围值 规范。

所以你必须在授权请求中指定openid

Azure 确实会为 OAuth 2.0 令牌响应返回一个 id 令牌(当 openid 范围不存在时)。

来自 Azure AD OAuth2.0 documentation

id_token

未签名的 JSON Web 令牌 (JWT)。该应用程序可以base64Url解码 此令牌的片段以请求有关用户的信息 已登录。应用程序可以缓存这些值并显示它们,但它 不应依赖它们来获得任何授权或安全边界。

正如文档所说,它只是用于显示最终用户。不得使用此 id 令牌进行身份验证/授权。

另一方面,对于正确的 OpenID Connect 令牌响应,Auzre 会向您发送一个签名的 id 令牌,

来自documentation

id_token

应用请求的 id_token。您可以使用 id_token 来 验证用户的身份并开始与用户的会话。

验证同一文档的 id_token 部分解释了如何验证令牌

希望这能解决您的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-24
    • 2019-04-02
    • 1970-01-01
    • 2019-01-03
    • 2016-07-05
    • 2021-09-17
    • 1970-01-01
    • 2019-03-09
    相关资源
    最近更新 更多