Adding ASP.NET Identity
Change base class from DbContext
to IdentityDbContext<ApplicationUser>
:
public class ApplicationUser : IdentityUser {}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
In Startup.cs
add identity and authentication:
services
.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services
.AddAuthentication(options =>
{
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(o =>
{
o.RequireHttpsMetadata = false;
o.SaveToken = true;
o.TokenValidationParameters = new TokenValidationParameters()
{
ValidAudience = Configuration["JWT:ValidIssuer"],
ValidIssuer = Configuration["JWT:ValidIssuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JWT:SignKey"])),
};
});
In Configure
add app.UseAuthentication();
before app.UseMvc
.
Token generation
public class LoginViewModel
{
[Required]
[EmailAddress]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
}
[Route("api/[controller]")]
public class TokenController : Controller
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly ILogger _logger;
private readonly IConfiguration _config;
public TokenController(
UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager,
ILogger<AccountController> logger,
IConfiguration config)
{
_userManager = userManager;
_signInManager = signInManager;
_logger = logger;
_config = config;
}
[AllowAnonymous]
[HttpPost("")]
public async Task<IActionResult> GenerateToken([FromBody] LoginViewModel model)
{
if (ModelState.IsValid)
{
var user = await _userManager.FindByEmailAsync(model.Email);
if (user != null)
{
var result = await _signInManager.CheckPasswordSignInAsync(user, model.Password, false);
if (result.Succeeded)
{
var claims = new List<Claim>
{
new Claim(JwtRegisteredClaimNames.Sub, user.Email),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
};
var roles = await _userManager.GetRolesAsync(user);
foreach (var role in roles)
claims.Add(new Claim(ClaimTypes.Role, role));
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["JWT:SignKey"]));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
_config["JWT:ValidIssuer"],
_config["JWT:ValidIssuer"],
claims,
expires: DateTime.Now.AddDays(30),
signingCredentials: creds);
return Ok(new
{
token = new JwtSecurityTokenHandler().WriteToken(token)
});
}
else
{
return BadRequest("Invalid username and password");
}
}
}
return BadRequest("Could not create token");
}
}