0
votes

I have been working on a system to authenticate and authorize users on my website using JSON Web Tokens. My system is just about completed, but I am running into an error when I attempt to use the [Authorize("Bearer")] attribute in my code. The error is as follows:

System.IdentityModel.Tokens.SecurityTokenInvalidSignatureException occurred Message: Exception thrown: 'System.IdentityModel.Tokens.SecurityTokenInvalidSignatureException' in Microsoft.IdentityModel.Logging.dll Additional information: IDX10503: Signature validation failed. Keys tried: ''. Exceptions caught: ''. token: '{"typ":"JWT","alg":"RS256","kid":null}.{"nameid":"6581f5a0-1775-4ce4-8650-a3d7e613b216","unique_name":"alex","AspNet.Identity.SecurityStamp":"8da933c3-0f88-42ea-876d-c07e99d1eecc","iss":"Uniti","aud":"Uniti","exp":1436849284,"nbf":1436845684}'

I don't understand why it isn't testing any keys with the JWT. I have an RSA key defined in my startup file. Without further dragging this on, I have provided the code that may be necessary to solve this error below.

My startup code (generating key and OAuthBearer options):

#region RSA Key Generation

        var rsa = new RSACryptoServiceProvider(2048);
        var rsaKey = rsa.ExportParameters(true);
        var key = new RsaSecurityKey(rsaKey);

        services.AddInstance(new SigningCredentials(key, SecurityAlgorithms.RsaSha256Signature, SecurityAlgorithms.Sha256Digest));

        #endregion

        services.AddInstance(new OAuthBearerAuthenticationOptions
        {
            SecurityTokenValidators = new List<ISecurityTokenValidator>
            {
                new JwtSecurityTokenHandler()
            },
            TokenValidationParameters = new TokenValidationParameters
            {
                IssuerSigningKey = key,
                ValidIssuer = "Uniti",
                ValidAudience = "Uniti"
            },
        });

        services.AddAuthorization();
        services.ConfigureAuthorization(auth =>
        {
            auth.AddPolicy("Bearer", builder =>
            {
                builder.AddAuthenticationSchemes(OAuthBearerAuthenticationDefaults.AuthenticationScheme);
                builder.RequireAuthenticatedUser();
            });
        });

My token generation code:

var claimsIdentity = (ClaimsIdentity) User.Identity;

            var handler = BearerOptions.SecurityTokenValidators.OfType<JwtSecurityTokenHandler>().First();
            var securityToken = handler.CreateToken(
                issuer: "Uniti",
                audience: "Uniti",
                signingCredentials: BearerCredentials,
                subject: claimsIdentity
                );

            var token = handler.WriteToken(securityToken);

Am I forgetting to add something somewhere, or am I generating the keys incorrectly? Thanks ahead of time if you can help me!

1

1 Answers

2
votes

I bet it's due to the incorrect way of registering the OAuth2 bearer options, as already explained in my previous answer: https://stackoverflow.com/a/31322654/542757

services.AddInstance(new OAuthBearerAuthenticationOptions());

When you use services.AddInstance, the OAuth2 bearer middleware is unable to retrieve the options (and thus, the key), as it internally uses IOptions<OAuthBearerAuthenticationOptions> and not OAuthBearerAuthenticationOptions.

This is the correct way to register the OAuth2 bearer options:

services.ConfigureOAuthBearerAuthentication(options => {
    // Configure the options used by the OAuth2 bearer middleware.
});