Signature Algorithm of "RS256" is Not Supported Err Msg .NET Auth0 NuGet Package

Auth0.AuthenticationApi v7.15.0 NuGet package used in .NET Core 3.1. Using Resource Owner Grant Flow.

I get the following error:

Signature algorithm of “RS256” is not supported. Expected the ID token to be signed with “HS256”.

when calling: await client.GetTokenAsync(tokenRequest).

If it helps, here is the top of the error stack trace:

at Auth0.AuthenticationApi.Tokens.SignedDecoder.AssertTokenAlgorithm(String token)
at Auth0.AuthenticationApi.Tokens.SignedDecoder.DecodeSignedToken(String token)
at Auth0.AuthenticationApi.IdTokenValidator.DecodeSignedToken(IdTokenRequirements requirements, String idToken, String clientSecret)

Full code below:

AuthenticationApiClient client = new AuthenticationApiClient(new Uri(_clientDomain));

var tokenRequest =  new ResourceOwnerTokenRequest
{
	ClientId = _clientId,
	ClientSecret = _clientSecret,
	Username = loginData.Email,
	Password = loginData.Pwd,
	Scope = REQUIRED_AUTH0_TOKEN_REQUEST_SCOPES,
	SigningAlgorithm = JwtSignatureAlgorithm.HS256
};

AccessTokenResponse auth0Tokens = await client.GetTokenAsync(tokenRequest);

All of this worked fine when I was using the RS256 default for the app and didn’t set the ClientSecret and SigningAlgorithm in ResourceOwnerTokenRequest.

The application is set to HS256 (and was for the last 4 hours - I know it says it can take some time to propogate).

How do I fix this and proceed with my goal of using HS256?

Note that I looked at the answer here - it doesn’t apply since the algo I am requesting and the algo in the app match (both HS256)

Hi there @v_auth welcome to the community!

Just out of curiosity - What’s the reason for wanting to use HS256? RS256 is generally encouraged across the board, see:

Let us know and we can go from there :smile:

Hi @tyf, thank you for the welcome!

I understand the reasoning for RS256 being encouraged by Auth0 (key rotation, not exposing a shared HS256 key if relying using the public key in the RS256 key pair) and agree with it.

The reason for me wanting to use HS256 here is a combination of a legacy app and a tight timeline - I need to integrate with Auth0 and the app uses HS256-signed JWTs already. There is built-in .NET Core middleware that can validate the tokens “out of the box”. With the RS256 JWK signatures, I would need to write custom middleware as far as I can tell, which introduces another failure point and costs time. Just to be clear, I need to accept both existing and Auth0 JWTs, and I don’t want to introduce additional custom code to handle the tokens differently, other than checking different shared keys (which is one line of code).

If you are interested, this is the built in .NET Core Middleware for checking token validity on all Authorized REST endpoints:

      .AddJwtBearer(x =>
      {
        x.RequireHttpsMetadata = false;
        x.SaveToken = true;
        x.TokenValidationParameters = new TokenValidationParameters
        {
          ValidateIssuerSigningKey = true,
          IssuerSigningKey = new SymmetricSecurityKey(AccessJwtDefaults.SHA_256_JWT_SIG_KEY_BYTES),
          ValidateIssuer = true,
          ValidateAudience = true,
          ClockSkew = TimeSpan.Zero
        };
      });

If I have HS256-signed tokens from Auth0, all I need to do is add to Auth0 key to IssuerSigningKey ={COLLECTION WITH OUR SYMMETRIC KEY AND THE AUTH0 SYMMETRIC KEY HERE}. Also, just for the sake of interest, they key is stored in Azure Key Vault, so it’s fairly secure.

1 Like

I pulled down the Auth0 .NET NuGet Package. As far as I can tell, it complete ignores ResourceOwnerTokenRequest's SigningAlgorithm property. From the NuGet Package:

        public async Task<AccessTokenResponse> GetTokenAsync(ResourceOwnerTokenRequest request, CancellationToken cancellationToken = default)
        {
            if (request == null)
                throw new ArgumentNullException(nameof(request));

            var body = new Dictionary<string, string> {
                { "client_id", request.ClientId },
                { "username", request.Username },
                { "password", request.Password },
                { "scope", request.Scope }
            };

            body.AddIfNotEmpty("client_secret", request.ClientSecret);
            body.AddIfNotEmpty("audience", request.Audience);
            body.AddIfNotEmpty("realm", request.Realm);
            body.Add("grant_type", String.IsNullOrEmpty(request.Realm) ? "password" : "http://auth0.com/oauth/grant-type/password-realm");

            var headers = String.IsNullOrEmpty(request.ForwardedForIp) ? null
                : new Dictionary<string, string> { { "auth0-forwarded-for", request.ForwardedForIp } };

            var response = await connection.SendAsync<AccessTokenResponse>(
                HttpMethod.Post,
                tokenUri,
                body,
                headers,
                cancellationToken
            ).ConfigureAwait(false);

            await AssertIdTokenValid(response.IdToken, request.ClientId, request.SigningAlgorithm, request.ClientSecret).ConfigureAwait(false);

            return response;

Will now check if the Auth0 API that this Auth0 package is calling handles HS256 or ignores it as well. Assuming the Auth0 API does handle HS256, my next step is one of the following:

  1. Call the Auth0 API directly, without the Auth0 NuGet package.
  2. Pull up a PR to send along the signing algorithm param.
  3. Extend the Auth0 NuGet package method locally.

UPDATE: As far as I can tell, the SigningAlgorithm property is not supported by the Auth0 API as well (see: Authentication API Explorer) and there is no way for me to get a HS256 token from Auth0, consequently none of the above approaches will work.

If my understanding is correct, I recommend either removing the ignored SigningAlgorithm property from the NuGet package, or throwing a clear exception indicating that HS256 isn’t supported for the Resource Owner Grant flow (if it’s supported in other flows).

Sorry for the double post - the following link worked for me after all. If you run into this problem - keep the last post in mind, this seems to only work for machine-to-machine.

The other thing to keep in mind here is that the .NET param really isn’t used and is misleading - HS256 vs RS256 is set at the client level in Auth0.

My apologies for the delay here and thanks for the detailed responses! That makes sense why you want to use HS256.

I definitely recommend opening up an issue against the repo itself in GitHub if you’re up for it! We always really appreciate the feedback.

Regarding the Resource Owner Password Grant (ROPG) - Thanks for the link to the previous topic, and confirming you got it working. I was able to test this using a web app configured in Auth0 to use HS256 paired with an API defined in Auth0 to use HS256 as well - The audience of my ROPG grant is set to this API. This last bit is what I was missing and causing some confusion on my end given the application was configured to use HS256 but still using RS256 at the API. For reference, I am going off of the following:

Thanks again for your your perseverance and for sharing with the community.

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.