Where to store JWT Token in .net core web api?

12,035

Alternatively, if you just wanted to authenticate using JWT the implementation would be slightly different

services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
    options.Events = new JwtBearerEvents
    {
        OnTokenValidated = context =>
        {
            var user = context.Principal.Identity.Name;
            //Grab the http context user and validate the things you need to
            //if you are not satisfied with the validation fail the request using the below commented code
            //context.Fail("Unauthorized");
            
            //otherwise succeed the request
            return Task.CompletedTask;
        }
    };
    options.RequireHttpsMetadata = false;
    options.SaveToken = true;
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = new SymmetricSecurityKey("MyVeryStrongKeyHiddenFromAnyone"),
        ValidateIssuer = false,
        ValidateAudience = false

    };
});

still applying use authentication before use MVC.

[Please note these are very simplified examples and you may need to tighten your security more and implement best practices such as using strong keys, loading configs perhaps from the environment etc]

Then the actual authentication action, say perhaps in AuthenticationController would be something like

[Route("api/[controller]")]
[Authorize]
public class AuthenticationController : Controller
{
    [HttpPost("authenticate")]
    [AllowAnonymous]
    public async Task<IActionResult> AuthenticateAsync([FromBody]LoginRequest loginRequest)
    {
        //LoginRequest may have any number of fields expected .i.e. username and password

        //validate user credentials and if they fail return
        //return Unauthorized();

        var claimsIdentity = new ClaimsIdentity(new Claim[]
           {
            //add relevant user claims if any
           }, "Cookies");

        var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
        await Request.HttpContext.SignInAsync("Cookies", claimsPrincipal);
        return Ok();
    }
}

in this instance I'm using cookies so I'm returning an HTTP result with Set Cookie. If I was using JWT, I'd return something like

[HttpPost("authenticate")]
public IActionResult Authenticate([FromBody]LoginRequest loginRequest)
{
    //validate user credentials and if they validation failed return a similar response to below
    //return NotFound();

    var tokenHandler = new JwtSecurityTokenHandler();
    var key = Encoding.ASCII.GetBytes("MySecurelyInjectedAsymKey");
    var tokenDescriptor = new SecurityTokenDescriptor
    {
        Subject = new ClaimsIdentity(new Claim[]
        {
            //add my users claims etc
        }),
        Expires = DateTime.UtcNow.AddDays(1),//configure your token lifespan and needed
        SigningCredentials = new SigningCredentials(new SymmetricSecurityKey("MyVerySecureSecreteKey"), SecurityAlgorithms.HmacSha256Signature),
        Issuer = "YourOrganizationOrUniqueKey",
        IssuedAt = DateTime.UtcNow
    };

    var token = tokenHandler.CreateToken(tokenDescriptor);
    var tokenString = tokenHandler.WriteToken(token);
    var cookieOptions = new CookieOptions();
    cookieOptions.Expires = DateTimeOffset.UtcNow.AddHours(4);//you can set this to a suitable timeframe for your situation 
    cookieOptions.Domain = Request.Host.Value;
    cookieOptions.Path = "/";
    Response.Cookies.Append("jwt", tokenString, cookieOptions);
    return Ok();
}
Share:
12,035
Tejas
Author by

Tejas

C# Developer

Updated on June 27, 2022

Comments

  • Tejas
    Tejas almost 2 years

    I am using web api for accessing data and I want to authenticate and authorize web api.For that I am using JWT token authentication. But I have no idea where should I store access tokens?

    What I want to do?

    1)After login store the token

    2)if user want to access any method of web api, check the token is valid for this user,if valid then give access.

    I know two ways

    1)using cookies

    2)sql server database

    which one is the better way to store tokens from above?

  • Tejas
    Tejas over 5 years
    Thanks for this solution but what is the IUserDomain here...?
  • Mpho Majenge
    Mpho Majenge over 5 years
    No problem, don't worry about them, those are basically just service orchestrations that help to do certain things like going to the database to validate users credentials or calling an internal authentication system. But do you get the basic that you don't really need to use database for storing tokens