Bjorn De Rijcke
Bjorn De Rijcke

Reputation: 683

JwtToken AudienceValidator missing audience in IEnumerable<string> audiences

I have an asp net core api where I need a custom validation for the "audience" claim in a JWT token.
This is possible via the AudienceValidator delegate (Microsoft.IdentityModel.Tokens) with signature:

bool CustumValidator(IEnumerable<string> audiences, SecurityToken securityToken, TokenValidationParameters validationParameters) 

The audiences should, as I understand it, contain a list of audiences in the token. The validationParameters contains all the TokenValidationParameters you register at startup. However, for me this parameter is empty.

In the configure method of my startup class if have the following:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IApplicationLifetime applicationLifetime)
    {
        //...

        // Setup JWT for the application.
        var jwtAppSettingOptions = ConfigurationRoot.GetSection(nameof(JwtIssuerOptions));
        var tokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidIssuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)],
            ValidateAudience = true,
            //ValidAudience = jwtAppSettingOptions[nameof(JwtIssuerOptions.Audience)], -- I have tried with both this property and the ValidAudiences one below
            ValidAudiences = new[] { jwtAppSettingOptions[nameof(JwtIssuerOptions.Audience)] },
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = _jwtSigningKey,
            RequireExpirationTime = true,
            ValidateLifetime = true,
            ClockSkew = TimeSpan.Zero,
            AudienceValidator = DoValidation // <-- my custom validation method, described below
        };

        //....
    }

And then I have this little test method, that for now, does nothing but return true.

    private bool DoValidation(IEnumerable<string> audiences, SecurityToken securityToken, TokenValidationParameters validationParameters)
    {
        var castedToken = securityToken as JwtSecurityToken;
        // Do Nothing
        return true;
    }

As said, this token in the piece above has no value in its audience property, and the IEnumerable<string> audiences is empty as well. I do not understand why. If I let the default validator method be (by not setting a delegate), it is able to see the token's audience and Forbids access if the audience is incorrect. So why does my custom method not get the audience(s) passed in?

Here's how I make the token:

        var jwt = new JwtSecurityToken(
            _jwtIssuerOptions.Issuer,
            String.IsNullOrWhiteSpace(_aud) ? _jwtIssuerOptions.Audience : _aud,
            claims,
            _jwtIssuerOptions.NotBefore,
            _jwtIssuerOptions.Expiration,
            _jwtIssuerOptions.SigningCredentials);

Thanks in advance.

Upvotes: 2

Views: 4326

Answers (1)

gsxrboy73
gsxrboy73

Reputation: 1482

I came across this question while trying to find the signature for the AudienceValidator delegate. (Thanks for that!)

The audiences enumerable is populated for me when I handle that delegate. One difference I see is that I do not specify the ValidAudiences parameter. You might try excluding that (assuming you haven't already solved this). Here is an example of my working code:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = true,
                    ValidateAudience = true,
                    ValidateLifetime = true,
                    ValidateIssuerSigningKey = true,
                    ValidIssuer = "MyIssuer",
                    IssuerSigningKey = new SymmetricSecurityKey(
                        Encoding.UTF8.GetBytes(Configuration["SecurityKey"])),
                    AudienceValidator = validateAudience
                };
            });

Upvotes: 1

Related Questions