Почему моя политика Azure Identity Experience Framework выдает JwtToken с алгоритмом HS256 вместо RS256?

Технический профиль выглядит так:

<TechnicalProfile Id="AAD-Common">
      <DisplayName>Multi-Tenant AAD</DisplayName>
      <Description>Login with your Contoso account</Description>
      <Protocol Name="OpenIdConnect"/>
      <Metadata>
        <Item Key="METADATA">https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration</Item>
        <!-- Update the Client ID below to the Application ID -->
        <Item Key="client_id">[the client id]</Item>
        <Item Key="response_types">id_token</Item>
        <Item Key="scope">openid</Item>
        <Item Key="response_mode">form_post</Item>
        <Item Key="HttpBinding">POST</Item>
        <Item Key="UsePolicyInRedirectUri">false</Item>
        <Item Key="DiscoverMetadataByTokenIssuer">true</Item>

        <!-- The commented key below specifies that users from any tenant can sign-in. Uncomment if you would like anyone with an Azure AD account to be able to sign in. -->
        <Item Key="ValidTokenIssuerPrefixes">https://login.microsoftonline.com/</Item>
      </Metadata>
      <CryptographicKeys>
        <Key Id="client_secret" StorageReferenceId="B2C_1A_AADAppSecret"/>
      </CryptographicKeys>
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="issuerUserId" PartnerClaimType="oid"/>
        <OutputClaim ClaimTypeReferenceId="tenantId" PartnerClaimType="tid"/>
        <OutputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="given_name" />
        <OutputClaim ClaimTypeReferenceId="surName" PartnerClaimType="family_name" />
        <OutputClaim ClaimTypeReferenceId="displayName" PartnerClaimType="name" />
        <OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="socialIdpAuthentication" AlwaysUseDefaultValue="true" />
        <OutputClaim ClaimTypeReferenceId="identityProvider" PartnerClaimType="iss" />
      </OutputClaims>
      <OutputClaimsTransformations>
        <OutputClaimsTransformation ReferenceId="CreateRandomUPNUserName"/>
        <OutputClaimsTransformation ReferenceId="CreateUserPrincipalName"/>
        <OutputClaimsTransformation ReferenceId="CreateAlternativeSecurityId"/>
        <OutputClaimsTransformation ReferenceId="CreateSubjectClaimFromAlternativeSecurityId"/>
      </OutputClaimsTransformations>
      <UseTechnicalProfileForSessionManagement ReferenceId="SM-SocialLogin"/>
    </TechnicalProfile>

Когда я проверяю этот токен носителя с помощью Microsoft.AspNetCore.Authentication.JwtBearer AddJwtBearer, я получаю эту ошибку:

token: '{"alg":"HS256","typ":"JWT","kid":"TwMsJMU3i_L7zOBKeOw7nWYHov3-eY70IsPfs1gT3aU"}.

{"exp":1588321433,"nbf":1588317833,"ver":"1.0","iss":"https://[mydomain].b2clogin.com/b3d62253-3d6e-453e-bb55-26d87c104a42/v2.0/","sub":"00000000-0000-0000-cdea-6895a0b0757c","aud":"dc3eeaae-c30a-4312-b346-b0919f7d4da1","acr":"b2c_1a_signup_signin","nonce":"defaultNonce","iat":1588317833,"auth_time":1588317833,"tid":"9188040d-6c67-4c5b-b112-36a304b66dad","name":"[my name]","idp":"https://login.microsoftonline.com/[my guid]/v2.0"}'.
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler: 2020-05-01 17:24:14,518 INFO Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler - JwtB2CBearer was not authenticated. Failure message: IDX10501: Signature validation failed. Unable to match key: 
kid: 'TwMsJMU3i_L7zOBKeOw7nWYHov3-eY70IsPfs1gT3aU'.
Exceptions caught:
 'System.NotSupportedException: IDX10634: Unable to create the SignatureProvider.
Algorithm: 'HS256', SecurityKey: 'Microsoft.IdentityModel.Tokens.RsaSecurityKey, KeyId: 'X5eXk4xyojNFum1kl2Ytv8dlNP4-c57dO6QGTVBwaNk', InternalId: 'e4c64ce7-9e7d-40e2-936a-6658d8f92f07'.'
 is not supported. The list of supported algorithms is available here: https://aka.ms/IdentityModel/supported-algorithms
   at Microsoft.IdentityModel.Tokens.CryptoProviderFactory.CreateSignatureProvider(SecurityKey key, String algorithm, Boolean willCreateSignatures)
   at Microsoft.IdentityModel.Tokens.CryptoProviderFactory.CreateForVerifying(SecurityKey key, String algorithm)
   at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateSignature(Byte[] encodedBytes, Byte[] signature, SecurityKey key, String algorithm, TokenValidationParameters validationParameters)
   at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateSignature(String token, TokenValidationParameters validationParameters)
'. 

Ключ политики в Identity Experience Framework настраивается с использованием «ручной» конфигурации, а секретный ключ — это то, что я создал в приложении Azure AD B2C.


person Maitland Marshall    schedule 01.05.2020    source источник
comment
B2C фактически уничтожает токен из этого технического профиля, поскольку это всего лишь токен от внешнего IdP. Он анализирует заявки и выдает собственный токен. Это настраивается техническим профилем JWTIssuer и связанными с ним криптографическими ключами. Ваша проблема связана с начальной настройкой ключей политики — aka.ms/ief. Снова настройте ключи подписи токена и шифрования. Убедитесь, что они указаны в техническом профиле JWTIssuer.   -  person Jas Suri - MSFT    schedule 01.05.2020
comment
Спасибо. Вы были абсолютно правы, и то, что вы сказали, заставило меня все понять.   -  person Maitland Marshall    schedule 01.05.2020


Ответы (1)


Я восстановил свои токены, как указано здесь: https://aka.ms/ief Подтвержден мой криптографический ключ из исходного сообщения. было установлено:

<CryptographicKeys>
    <Key Id="client_secret" StorageReferenceId="B2C_1A_TokenSigningKeyContainer"/>
</CryptographicKeys>

Я также убедился, что для моего JwtIssuer в TrustFrameworkBase.xml установлены следующие ключи:

<CryptographicKeys>
    <Key Id="issuer_secret" StorageReferenceId="B2C_1A_TokenSigningKeyContainer" />
    <Key Id="issuer_refresh_token_key" StorageReferenceId="B2C_1A_TokenEncryptionKeyContainer" />
 </CryptographicKeys>

Это все равно не пройдет проверку, я получу эту ошибку:

IDX10501: Signature validation failed. Unable to match keys

Руководствуясь этим сообщением: IDX10501: проверка подписи не удалась. Невозможно сопоставить ключи Мне удалось заставить его работать, установив IssuerSigningKeys при настройке JwtBearerOptions:

internal class JwtBearerOptionsConfiguration : IConfigureNamedOptions<JwtBearerOptions>
    {
        private readonly AzureAdB2COptions b2cOptions;
        private readonly IMetaDataFromClaimsPrincipalService metaDataFromClaimsService;

        public JwtBearerOptionsConfiguration(IOptions<AzureAdB2COptions> b2cOptions, IMetaDataFromClaimsPrincipalService metaDataFromClaims)
        {
            this.b2cOptions = b2cOptions.Value;
            this.metaDataFromClaimsService = metaDataFromClaims;
        }

        public void Configure(JwtBearerOptions options)
        {
            this.Configure(Options.DefaultName, options);
        }

        public void Configure(string name, JwtBearerOptions options)
        {
            AzureAdB2COptions currentOptions = this.b2cOptions;

            options.Audience = currentOptions.ClientId;
            options.Authority = currentOptions.BuildAuthority(currentOptions.SignUpSignInPolicyIds.Last());

            options.IncludeErrorDetails = true;

            var configManager = new ConfigurationManager<OpenIdConnectConfiguration>($"{options.Authority}/.well-known/openid-configuration", new OpenIdConnectConfigurationRetriever());
            var openidconfig = configManager.GetConfigurationAsync().Result;

            options.TokenValidationParameters = new TokenValidationParameters
            {
                IssuerSigningKeys = openidconfig.SigningKeys,
                ValidateIssuerSigningKey = true
            };

            options.Events = new JwtBearerEvents
            {
                OnTokenValidated = this.OnTokenValidated,
                OnAuthenticationFailed = this.OnAuthenticationFailed
            };
        }

        private Task OnAuthenticationFailed(AuthenticationFailedContext arg)
        {
            return Task.CompletedTask;
        }

        private Task OnTokenValidated(TokenValidatedContext arg)
        {
            // Check if the authenticated principal has a valid Trust Framework Policy, otherwise do not grant access
            string tfp = this.metaDataFromClaimsService.GetTrustFrameworkPolicy(arg.Principal);

            if (!this.b2cOptions.SignUpSignInPolicyIds.Contains(tfp))
                arg.Fail("Could not validate the Trust Framework Policy");



            return Task.CompletedTask;
        }

    }

Спасибо @Джас Сури

person Maitland Marshall    schedule 01.05.2020