I use JWT tokens in my ASP.NET Core 2 web application
If the JWT token fails I still want the controller method to be hit but the ASP.NET Identity User
object will just be null. Currently the controller method won't get entered if authentication fails so I can't apply logic inside the method to deal with non authenticated users which I want to deal with as guests instead of blocking them.
My code:
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication()
.AddJwtBearer(cfg =>
{
cfg.TokenValidationParameters = new TokenValidationParameters()
{
ValidIssuer = _config["Tokens:Issuer"],
ValidAudience = _config["Tokens:Audience"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Tokens:Key"]))
};
});
When a user logs in
private IActionResult CreateToken(ApplicationUser user, IList<string> roles)
{
var claims = new List<Claim>
{
new Claim(JwtRegisteredClaimNames.Sub, user.Id.ToString()),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(JwtRegisteredClaimNames.UniqueName, user.UserName)
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Tokens:Key"]));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
_config["Tokens:Issuer"],
_config["Tokens:Audience"],
claims.ToArray(),
expires: DateTime.Now.AddMinutes(60),
signingCredentials: creds);
var results = new
{
token = new JwtSecurityTokenHandler().WriteToken(token),
expiration = token.ValidTo,
};
return Created("", results);
I make sure after authenticated the various API calls pass the JWT token.
In my Controller I make use of an Authorize attribute
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public class MyController : Controller
{
This allows me to capture the logged in user with the following code for the various API calls
var loggedInUser = User.Identity.Name;
If I remove the authorize attribute then User.Identity.Name
will always be null even if the user is authenticated.
How do I use the authorize attribute but still allow the controller method to be entered if the token is not valid? I want to use the same method for both Authorized and non Authorized users to be entered. I will then use the User.Identity.Name
to determine if they are not authenticated and have guest user logic inside the method for them.
Go to "Authorization" tab, select "Bearer Token" authorization type and for value just enter {{jwt-token}} . That's it. Now you have to execute login request only once and JWT token will automatically be used in all other request.
To authenticate a user, a client application must send a JSON Web Token (JWT) in the authorization header of the HTTP request to your backend API. API Gateway validates the token on behalf of your API, so you don't have to add any code in your API to process the authentication.
First, you have to register your policy in the ConfigureServices() method of the Startup class, as part of the authorization service configuration.
It's actually easier than you might expect. You can just use both Authorize
and AllowAnonymous
, like so:
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[AllowAnonymous]
public class MyController : Controller
If authorization was successful, you'll have an authenticated User
(User.Identity.IsAuthenticated = true
), otherwise, you will have an anonymous User
.
I'm not sure when this changed but my application is on ASP.NET Core 3.1 and without my actions/endpoints specifying that I require authorization, the authentication middleware still provides the information I require inside my ClaimsPrincipal when a valid token is provided and a blank principal when no token is specified.
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