Reputation: 683
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
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