Reputation: 23
I have a .NET Core Web API that accepts a JWT bearer token from a Google sign-in button for authentication. It appears that authentication is succeeding as I am able to get the ClaimsPrincipal from the HttpContext.User in my controller methods. However, when I add the [Authorize] attribute to my controller, I get back a 403 for failed authorization. I believe I am using the default authorization which should allow any authenticated user. What am I missing?
Here is the SecurityTokenValidator that I am using:
public ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken)
{
var payload = GoogleJsonWebSignature.ValidateAsync(securityToken, _validationSettings).Result;
validatedToken = _jwtHandler.ReadJwtToken(securityToken);
var claims = new List<Claim>
{
new Claim(ClaimTypes.NameIdentifier, payload.Name),
new Claim(ClaimTypes.Name, payload.Name),
new Claim(JwtRegisteredClaimNames.FamilyName, payload.FamilyName),
new Claim(JwtRegisteredClaimNames.GivenName, payload.GivenName),
new Claim(JwtRegisteredClaimNames.Email, payload.Email),
new Claim(JwtRegisteredClaimNames.Sub, payload.Subject),
new Claim(JwtRegisteredClaimNames.Iss, payload.Issuer),
};
var principal = new ClaimsPrincipal();
principal.AddIdentity(new ClaimsIdentity(claims));
return principal;
}
Here is where I wire that up in Startup.cs:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(o =>
{
var googleClientId = Configuration[ConfigurationKeys.GoogleClientId];
if(googleClientId == null)
{
throw new Exception($"Configuration property not found: {ConfigurationKeys.GoogleClientId}");
}
var validationSettings = new ValidationSettings();
validationSettings.Audience = new List<string> { googleClientId };
o.SecurityTokenValidators.Clear();
o.SecurityTokenValidators.Add(new GoogleSecurityTokenValidator(validationSettings));
});
Here is where I configure the app:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseCors(x => x
.AllowAnyMethod()
.AllowAnyHeader()
.SetIsOriginAllowed(origin => true)
.AllowCredentials()
);
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
Upvotes: 1
Views: 474
Reputation: 23
I have finally found the problem. When creating a ClaimsIdentity object, the AuthenticationType needs to be specified. For my solution, I changed set it to JwtBearerDefaults.AuthenticationScheme
although I'm not sure that is correct.
principal.AddIdentity(new ClaimsIdentity(claims, JwtBearerDefaults.AuthenticationScheme));
I found the answer here: https://stackoverflow.com/a/20254797/3984834
Upvotes: 1