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");
    }
}

results matching ""

    No results matching ""