I am trying to validate a JWT token being passed onto a C# application. I confirmed that the token is being sent with every request. If I decode it manually everything works fine (I see the claims). However when I enable Authorization I get a 404 from the (Angular) client when I try to access the page. My theory is that Angular is sending an OPTIONS request that is failing because it cant Auth with the token properly. Any advice on how to confirm this is the issue, and troubleshoot it?
Auth via claim in token
[Authorize(Policy = "IsEmployee")]
[HttpGet("TestTokenAccess")]
public JsonResult TestTokenAccess()
{
return Json("token decoded. you have claim IsEmployee=yes");
}
Manual token decode
[HttpGet("TestDecodeToken")]
public JsonResult TestDecodeToken()
{
//https://shellmonger.com/2015/07/18/decoding-an-auth0-json-web-token-with-c/
if (this.HttpContext.Request.Headers.ContainsKey("Authorization"))
{
var authHeader = this.HttpContext.Request.Headers["Authorization"];
var authBits = authHeader.ToString().Split(' ');
if (authBits.Length != 2)
{
return Json("{error:\"auth bits needs to be length 2\"}");
}
if (!authBits[0].ToLowerInvariant().Equals("bearer"))
{
return Json("{error:\"authBits[0] must be bearer\"}");
}
var secret = "xxxxx";
//Install-Package JWT -Version 4.0.0
try
{
var json = new JwtBuilder()
.WithSecret(secret)
//.MustVerifySignature()
.Decode(authBits[1]);
return Json(json);
}
catch (TokenExpiredException)
{
return Json("Token has expired");
}
catch (SignatureVerificationException)
{
return Json("Token has invalid signature");
}
catch (Exception e)
{
return Json($"other token err: {e.Message}");
}
}
return Json("no token");
}
Startup.cs inside of ConfigureServices, but above the AddMVC() call
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Authority = Configuration["JwtIssuer"];
options.Audience = Configuration["JwtIssuer"];
options.RequireHttpsMetadata = true;
options.SaveToken = true;
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = Configuration["JwtIssuer"],
ValidAudience = Configuration["JwtIssuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JwtKey"]))
};
}
);
services.AddAuthorization(options =>
{
options.AddPolicy("IsEmployee", policy => policy.Requirements.Add(new IsEmployeeRequirement("yes")));
});
services.AddSingleton<IAuthorizationHandler, IsEmployeeAuthorizationHandler>();
appsettings.json
"JwtKey": "xxx",
"JwtIssuer": "http://localhost:44362/",
"JwtExpireDays": 30
snippet from web.config enable CORS
<!--added to enable CORS for Angular-->
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="https://localhost:44362/" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
</customHeaders>
</httpProtocol>