Create token authentication in ASP.NET Core

How to create token in ASP.NET Core

In this post I will demonstrate how to create a authentication token in an ASP.NET Core Web Api application.

Example

At first I add some claims to token e.g NameIdentifier, and DateOfBirth.

var claims = new []
{
    new Claim(ClaimTypes.NameIdentifier, "Some identifier"),
    new Claim(ClaimTypes.DateOfBirth, DateTime.Now.AddYears(-25).ToShortDateString())
};

Now I need to create secret key for token. Let’s add it in appsettings.json. It’s looks like below:

{
  "AppSettings":{
    "TokenSecret":"Your super secret key for token"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*"
}

Then create a key symmetric security key with our secret value from appsettings and generate credentials, using some sort of hashing algorithm (in this case HmacSha512).

var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration.GetSection("AppSettings:TokenSecret").Value));

var credentials = new SigningCredentials(key,SecurityAlgorithms.HmacSha512);

It remains to create a token from the above-created properities.

var tokenDescriptor = new SecurityTokenDescriptor
{
    Subject = new ClaimsIdentity(claims),
    Expires = DateTime.Now.AddHours(1),
    SigningCredentials = credentials
};

var tokenHandler = new JwtSecurityTokenHandler();

var token = tokenHandler.CreateToken(tokenDescriptor);

In this way, create actions in the controller that will create a token and return it to us.

[HttpPost]
public IActionResult Authorize()
{
    var claims = new []
    {
        new Claim(ClaimTypes.NameIdentifier, "Some idetifier"),
        new Claim(ClaimTypes.DateOfBirth, DateTime.Now.AddYears(-25).ToShortDateString())
    };
    var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration.GetSection("AppSettings:TokenSecret").Value));

    var credentials = new SigningCredentials(key,SecurityAlgorithms.HmacSha512);

    var tokenDescriptor = new SecurityTokenDescriptor
    {
        Subject = new ClaimsIdentity(claims),
        Expires = DateTime.Now.AddHours(1),
        SigningCredentials = credentials
    };

    var tokenHandler = new JwtSecurityTokenHandler();

    var token = tokenHandler.CreateToken(tokenDescriptor);

    return Ok(new {token= tokenHandler.WriteToken(token)});
}

Voilà!

After calling Authorize method in postman, we get a token.

token

We can verify its correctness on the jwt.io website.

decode token

We see that everything is ok with our token.

ASP.NET Core Authorization

Let’s now use our generated token to secure our application. To configure the application to use the token jwt we need to add some behavior in start up.

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    services.AddAuthentication(x =>
    {
        x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    })
        .AddJwtBearer(options =>
        {
            options.SaveToken = true;
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration.GetSection("AppSettings:TokenSecret").Value)),
                ValidateIssuer = false,
                ValidateAudience = false
            };
        });
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseHsts();
    }
    app.UseAuthentication();
    app.UseMvc();
}

Put the authorizate attribute on our value controller to test the authorization action.

[Route("api/[controller]")]
[ApiController]
[Authorize]
public class ValuesController : ControllerBase
{
    // GET api/values
    [HttpGet]
    public ActionResult<IEnumerable<string>> Get()
    {
        return new string[] { "value1", "value2" };
    }
}

After calling the action above without providing the token, we get the 401 code of unauthorized.

error authorization

When we pass our token in the header, the application returns us the correct information.

correct authorization

Link to whole code – github.

Leave a Reply

Your email address will not be published. Required fields are marked *