I am trying to test that my .RequireAuthorization()
are working in my custom minimal api endpoints by creating a JWT token from my CallingApi to the MinApi.
In my CallingApi, I am adding the generated token to the auth header.
var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", TokenGenerator.GenerateToken());
var url = $"https://localhost:7215/api/users";
var response = await httpClient.GetAsync(url);
response.EnsureSuccessStatusCode();
return Ok(await response.Content.ReadAsStringAsync());
The token generating code looks like this:
public static String GenerateToken()
{
var key = Encoding.UTF8.GetBytes("CallMinApiKey-ThisNeedsToBePrettyLong");
var tokenHandler = new JwtSecurityTokenHandler();
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, "TestUser")
}),
Expires = DateTime.UtcNow.AddHours(1),
Issuer = "TestIssuer",
Audience = "TestAudience",
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateJwtSecurityToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
}
When I was calling my MinApi, I was getting a 401 status code. To get what the reason was, I added a token validation method in my CallingApi, which looks like this:
public static String GenerateToken()
{
var key = Encoding.UTF8.GetBytes("CallMinApiKey-ThisNeedsToBePrettyLong");
var tokenHandler = new JwtSecurityTokenHandler();
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, "TestUser")
}),
Expires = DateTime.UtcNow.AddHours(1),
Issuer = "TestIssuer",
Audience = "TestAudience",
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateJwtSecurityToken(tokenDescriptor);
var testTokenString = tokenHandler.WriteToken(token);
TestValidateToken(testTokenString);
return testTokenString;
}
public static Boolean TestValidateToken(String testTokenString)
{
var token = testTokenString;
var key = Encoding.UTF8.GetBytes("CallMinApiKey-ThisNeedsToBePrettyLong");
var tokenHandler = new JwtSecurityTokenHandler();
var validationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateIssuerSigningKey = true,
ValidIssuer = "TestIssuer",
ValidAudience = "TestAudience",
IssuerSigningKey = new SymmetricSecurityKey(key)
};
try
{
tokenHandler.ValidateToken(token, validationParameters, out SecurityToken validatedToken);
Console.WriteLine("Token is valid.");
return true;
}
catch (Exception ex)
{
Console.WriteLine($"Unknown error: {ex.Message}");
}
return false;
}
Each time, validation throws an exception and the message is: IDX10206: Unable to validate audience. The 'audiences' parameter is empty.
But, I put my token in jwt.io and it has an “aud” value see:
my token parsed on jwt.io
What am I doing incorrectly?