18
votes

I have an API that sits behind an API Gateway. The API Gateway validates the bearer token before passing the request along to the API.

My API the uses the the asp.net core 2.0 native authentication and claims based authorization framework. The grunt work of getting the claims from the JWT token is done by the middleware in Microsoft.AspNetCore.Authentication.JwtBearer.

This middle ware can be configured to ignore the expiration date on the token and it is also possible to specify a local public key so it is not necessary to contact the token Authority to obtain one, but is it possible to just disable the signature validation on the token?

This would allow use of unsigned tokens for ad-hoc testing in development and prevent double validation (gateway and then API) in production.

3
I think if you clear the default token validator and provide your own ISecurityTokenValidator that skips any validation should do it. github.com/AzureAD/…Mardoxx
@Eli Algranti Could find any way to do this? I'm currently stuck on the same issue.Ong Ming Soon
Just to share my design. I'm using this approach as well to disable the double validation at gateway and api level. I'm using nginx+ as the api gateway, identityserver4 to generate the token. Api gateway will do the validation. This will remove the need of token validation to be done in the api level(which it can be coming from .net , java or etc)Ong Ming Soon

3 Answers

35
votes

Try this. Finally, I got it to work after so much of trying.

public TokenValidationParameters CreateTokenValidationParameters()
{
    var result = new TokenValidationParameters
    {
    ValidateIssuer = false,
    ValidIssuer = ValidIssuer,

    ValidateAudience = false,
    ValidAudience = ValidAudience,

    ValidateIssuerSigningKey = false,
    //IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(SecretKey)),
    //comment this and add this line to fool the validation logic
    SignatureValidator = delegate(string token, TokenValidationParameters parameters)
    {
        var jwt = new JwtSecurityToken(token);

        return jwt;
    },

    RequireExpirationTime = true,
    ValidateLifetime = true,

    ClockSkew = TimeSpan.Zero,
    };

    result.RequireSignedTokens = false;

    return result;
}
3
votes

You may setup token validation using JwtBearerOptions.TokenValidationParameters. You could check all available parameters from the class definition.

Contains a set of parameters that are used by a Microsoft.IdentityModel.Tokens.SecurityTokenHandler when validating a Microsoft.IdentityModel.Tokens.SecurityToken.

Set All ValidateXXX and RequireXXX bool properties to false if you want to disable validation at all:

.AddJwtBearer("<authenticationScheme>", configureOptions =>
{
   options.TokenValidationParameters.ValidateActor = false;
   options.TokenValidationParameters.ValidateAudience = false;
   options.TokenValidationParameters.ValidateIssuerSigningKey = false;
   ...
}

As an another option you can override the default token signature validation by setting own implementation to JwtBearerOptions.SignatureValidator:

// Gets or sets a delegate that will be used to validate the signature of the token.
//
// Remarks:
//  If set, this delegate will be called to signature of the token, instead of normal
//  processing.
public SignatureValidator SignatureValidator { get; set; }

where SignatureValidator delegate is defined as:

public delegate SecurityToken SignatureValidator(string token, TokenValidationParameters validationParameters);
1
votes

I was able to clean up the code a bit, showing that we can just change the flag and with a bit more consistency when setting the flags.

services.AddAuthentication(o =>
{
    o.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    o.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
    .AddJwtBearer(o =>
    {
        o.RequireHttpsMetadata = false;
        o.SaveToken = true;
        o.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = false,
            ValidateAudience = false,
            ValidateIssuerSigningKey = false,
            ValidateLifetime = false,
            RequireExpirationTime = false,
            RequireSignedTokens = false
        };
    });