This tutorial shows you how to authorize Web API in ASP.NET Core using JWT (Json Web Token). JWT is a means of representing claims to be transferred between two parties. The claims in a JWT are encoded as a JSON object that is digitally signed using JSON Web Signature (JWS) and/or encrypted using JSON Web Encryption
To play demo we will create a new asp.net core web application, then select Web API project template and change Authentication to Individual accounts in the Web API project template
To config JWT in ASP.NET Core, we will add a config to the appsetting.json file as below
{
"ConnectionStrings": {
"DefaultConnection": "Server=.;Database=invoice;User ID=sa;Password=123@qaz;"
},
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Warning"
}
},
"JwtKey": "ace208cfbd61f333690158aac11a67b9",
"JwtIssuer": "http://c-sharpcode.com",
"JwtExpires": 30
}
You can enter private key to JwtKey
Open the Startups class and modify the ConfigServices method as below
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
// Add application services.
services.AddTransient<IEmailSender, EmailSender>();
services.ConfigureApplicationCookie(options =>
{
options.LoginPath = new PathString("/Account/Login");
options.LogoutPath = new PathString("/Account/Logout");
options.Events.OnRedirectToLogin = context =>
{
if (context.Request.Path.StartsWithSegments("/api") && context.Response.StatusCode == StatusCodes.Status200OK)
{
context.Response.Clear();
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
return Task.FromResult<object>(null);
}
context.Response.Redirect(context.RedirectUri);
return Task.FromResult<object>(null);
};
});
// ===== Add Jwt Authentication ========
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
services
.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(cfg =>
{
cfg.RequireHttpsMetadata = false;
cfg.SaveToken = true;
cfg.TokenValidationParameters = new TokenValidationParameters
{
ValidIssuer = Configuration["JwtIssuer"],
ValidAudience = Configuration["JwtIssuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JwtKey"])),
ClockSkew = TimeSpan.Zero
};
});
services.AddMvc();
}
To create a token key, you can open AccountController then add GenerateJwtToken method to generate token key
private readonly IConfiguration _configuration;
public AccountController(
UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager,
IEmailSender emailSender,
ILogger<AccountController> logger, IConfiguration configuration)
{
_userManager = userManager;
_signInManager = signInManager;
_emailSender = emailSender;
_logger = logger;
_configuration = configuration;
}
private object GenerateJwtToken(IdentityUser user)
{
var claims = new List<Claim>
{
new Claim(JwtRegisteredClaimNames.Sub, user.Email),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(ClaimTypes.NameIdentifier, user.Id)
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JwtKey"]));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var expires = DateTime.Now.AddDays(Convert.ToDouble(_configuration["JwtExpires"]));
var token = new JwtSecurityToken(
_configuration["JwtIssuer"],
_configuration["JwtIssuer"],
claims,
expires: expires,
signingCredentials: creds
);
return new JwtSecurityTokenHandler().WriteToken(token);
}
Adding a CreateToken action allows you to get a token key when you successfully log on
[HttpPost]
[AllowAnonymous]
public async Task<object> CreateToken([FromBody] LoginViewModel model)
{
var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, false, false);
if (result.Succeeded)
{
var user = _userManager.Users.SingleOrDefault(r => r.Email == model.Email);
return GenerateJwtToken(user);
}
throw new ApplicationException("Invalid login attempt!");
}
Now you can use RestSharp to play demo, see How to use Restsharp to access Web API in C#