c# - 在每个请求上验证 OpenId IdToken

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

我尝试验证每次请求时从 Azure AD 获取的 IdToken,但我不断收到错误消息,指出 token 上没有签名。当我验证访问 token 时,它可以工作,但我宁愿使用 Id token ,因为它包含用户声明。有没有办法让 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;
        }
    }

更新

因此,无论出于何种原因,即使没有提供范围,我也收到了 claim 。我现在所做的只是将查询参数添加到范围的 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 Connect specification

Scope

REQUIRED. OpenID Connect requests MUST contain the openid scope value. If the openid scope value is not present, the behavior is entirely unspecified. Other scope values MAY be present. Scope values used that are not understood by an implementation SHOULD be ignored. See Sections 5.4 and 11 for additional scope values defined by this specification.

因此您必须在授权请求中指定openid

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

来自 Azure AD OAuth2.0 documentation ,

id_token

An unsigned JSON Web Token (JWT). The app can base64Url decode the segments of this token to request information about the user who signed in. The app can cache the values and display them, but it should not rely on them for any authorization or security boundaries.

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

另一方面,为了获得正确的 OpenID Connect token 响应,Auzre 会向您发送一个签名的 ID token ,

来自documentation

id_token

The id_token that the app requested. You can use the id_token to verify the user's identity and begin a session with the user.

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

希望这能解决您的问题。

关于c# - 在每个请求上验证 OpenId IdToken,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47658020/

相关文章:

c# - 在特定情况下自动滚动列表框

c# - Windows Phone 8 Geolocator 缓存位置

azure - 人工工厂 : Error : Ping failed since server state is blocked

python - Azure Web应用程序部署到tmp文件夹而不是wwwroot

c# - 使用 Azure Active Directory 配置 URL 重定向

azure - SPA 应用程序 (Angular 5) 如何访问单独的 WebAPI(在 Azure AD 下)

c# - 使用 OpenXmlWriter SAX 创建带有样式标签的 Excel 文件

azure - 将托管身份与 Cosmos Db 表 Api 结合使用

azure - 如何将 Easy Auth 与 .NET Core 3.1 MVC 应用程序集成?

c# - 从 WinForms 应用程序重新启动计算机?