This is my token decoder. When I try to decode it, my principal ends up being null thus leading to this error:
'IDX10208: Unable to validate audience. validationParameters.ValidAudience is null or whitespace and validationParameters.ValidAudiences is null.'
When I decode my token to check
"nbf": 1539167980, "exp": 1539168580, "iat": 1539167980, "iss": "http://localhost:55260", "aud": "http://localhost:55260"
This is the host that my token generator runs on as well. Why is the principal causing issues?
public class DecodeToken
{
private IConfiguration configuration;
public DecodeToken(IConfiguration configuration)
{
this.configuration = configuration;
}
public AuthenticationDto Decode(String Input)
{
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["JwtAuthentication:SecurityKey"]));
var handler = new JwtSecurityTokenHandler();
var tokenSecure = handler.ReadToken(Input) as SecurityToken;
var validations = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = key,
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = false
};
SecurityToken securityToken;
var principal = handler.ValidateToken(Input, validations, out securityToken);
var jwtSecurityToken = securityToken as JwtSecurityToken;
if (jwtSecurityToken == null || !jwtSecurityToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256, StringComparison.InvariantCultureIgnoreCase))
{
throw new SecurityTokenException("Invalid Token");
}
AuthenticationDto authenticationDto = new AuthenticationDto
{
Email = principal.Claims.Where(c => c.Type == "Email").Select(c => c.Value).SingleOrDefault(),
UserName = principal.Claims.Where(c => c.Type == "UserName").Select(c => c.Value).SingleOrDefault(),
FirstName = principal.Claims.Where(c => c.Type == "FirstName").Select(c => c.Value).SingleOrDefault(),
LastName = principal.Claims.Where(c => c.Type == "LastName").Select(c => c.Value).SingleOrDefault(),
PhoneNumber = principal.Claims.Where(c => c.Type == "PhoneNumber").Select(c => c.Value).SingleOrDefault(),
Id = principal.Claims.Where(c => c.Type == "Id").Select(c => c.Value).SingleOrDefault(),
ExpiryDateTime = principal.Claims.Where(c => c.Type == "exp").Select(c => c.Value).SingleOrDefault(),
Roles = principal.Claims.Where(c => c.Type == "Roles").Select(c => c.Value).ToList(),
};
return authenticationDto;
}
}
This is what my Startup.cs looks like:
services.AddAuthentication(options => {
options.DefaultAuthenticateScheme = "Jwt";
options.DefaultChallengeScheme = "Jwt";
})
.AddJwtBearer("Jwt", options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JwtAuthentication:SecurityKey"])),
ValidateIssuer = true,
ValidIssuer = Configuration["JwtAuthentication:Issuer"],
ValidateAudience = true,
ValidAudience = Configuration["JwtAuthentication:Audience"],
ValidateLifetime = true, //validate the expiration and not before values in the token
ClockSkew = TimeSpan.Zero //5 minute tolerance for the expiration date
};
options.Events = new JwtBearerEvents
{
OnAuthenticationFailed = context =>
{
if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
{
context.Response.Headers.Add("Token-Expired", "true");
}
return Task.CompletedTask;
}
};
});
Have I configured something wrong?
Your error appears to make perfect sense. In ConfigureServices
, you're setting up the TokenValidationParameters
so that it validates your issuer/audience and you're providing values for ValidIssuer
and ValidAudience
, but you're not doing the same in your Decode
function, where you're only setting ValidateIssuer
and ValidateAudience
without setting the values that you expect. You need to configure these on your validations
variable in Decode
, like this:
var validations = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = key,
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = false,
// Add these...
ValidIssuer = configuration["JwtAuthentication:Issuer"],
ValidAudience = configuration["JwtAuthentication:Audience"]
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With