Step by step guide for Authentication and Authorization in ASP.NET Core using JWT & Identity

Step by step guide for Authentication and Authorization in ASP.NET Core using JWT & Identity

Building secure applications begins with a strong foundation in authentication and authorization. With ASP.NET Core, implementing this becomes much simpler thanks to the seamless integration of Identity and JSON Web Tokens (JWT). In this guide, we’ll walk through the entire setup step-by-step, using clear, beginner-friendly explanations to help you secure your application with confidence.

What is ASP.NET Core?

ASP.NET Core is a modern framework by Microsoft used to build fast, secure, and scalable web applications and APIs. It works on multiple platforms and supports clean, structured development.

Authentication

Authentication is the process of verifying who the user is. It checks username and password and confirms identity.

Authorization

Authorization decides what an authenticated user is allowed to do. It controls access to features and data.

In simple terms, authentication answers the question who are you, while authorization answers what are you allowed to do.

Introduction to JWT and Identity

JWT or JSON Web Token is a secure way to transmit user data between client and server. Once a user logs in, the server generates a token. This token is sent with every request.

ASP.NET Core Identity is a built-in system that handles user registration, login, roles, and password management.

1. Create a New ASP.NET Core Web API Project

Create a new project with Identity and Entity Framework support.

dotnet new webapi -o AuthApi        

Install Identity packages if not included.

dotnet add package Microsoft.AspNetCore.Identity.EntityFrameworkCore
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer        

2. Configure the Database Context

Add an ApplicationDbContext that inherits from IdentityDbContext.

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }
}

public class ApplicationUser : IdentityUser
{
}        

Add connection string in appsettings.json.

"ConnectionStrings": {
  "DefaultConnection": "Server=.;Database=AuthDemoDb;Trusted_Connection=True;"
}        

Register in Program.cs.

builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));        

3. Add ASP.NET Core Identity

Register Identity so the app can create and manage users.

builder.Services.AddIdentity<ApplicationUser, IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultTokenProviders();        

4. Add JWT Authentication

Add JWT settings inside appsettings.json.

"Jwt": {
  "Key": "ThisIsMySuperSecretKey123",
  "Issuer": "AuthApi",
  "Audience": "AuthApiUsers"
}        

Configure JWT in Program.cs.

builder.Services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        ValidIssuer = builder.Configuration["Jwt:Issuer"],
        ValidAudience = builder.Configuration["Jwt:Audience"],
        IssuerSigningKey = new SymmetricSecurityKey(
            Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]))
    };
});        

Enable authentication and authorization.

app.UseAuthentication();
app.UseAuthorization();        

5. Create a Register Endpoint

This endpoint creates new users in the system.

[HttpPost("register")]
public async Task<IActionResult> Register(RegisterDto model)
{
    var user = new ApplicationUser
    {
        UserName = model.Email,
        Email = model.Email
    };

    var result = await _userManager.CreateAsync(user, model.Password);

    if (!result.Succeeded)
        return BadRequest(result.Errors);

    return Ok("User created successfully.");
}

public class RegisterDto
{
    public string Email { get; set; }
    public string Password { get; set; }
}        

6. Create a Login Endpoint with JWT Token Generation

This endpoint checks the user and returns a JWT.

[HttpPost("login")]
public async Task<IActionResult> Login(LoginDto model)
{
    var user = await _userManager.FindByEmailAsync(model.Email);

    if (user == null)
        return Unauthorized("Invalid credentials.");

    if (!await _userManager.CheckPasswordAsync(user, model.Password))
        return Unauthorized("Invalid credentials.");

    var claims = new[]
    {
        new Claim(JwtRegisteredClaimNames.Sub, user.Id),
        new Claim(JwtRegisteredClaimNames.Email, user.Email)
    };

    var key = new SymmetricSecurityKey(
        Encoding.UTF8.GetBytes(_config["Jwt:Key"]));

    var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

    var token = new JwtSecurityToken(
        issuer: _config["Jwt:Issuer"],
        audience: _config["Jwt:Audience"],
        claims: claims,
        expires: DateTime.UtcNow.AddHours(2),
        signingCredentials: creds);

    return Ok(new
    {
        token = new JwtSecurityTokenHandler().WriteToken(token),
        expiration = token.ValidTo
    });
}

public class LoginDto
{
    public string Email { get; set; }
    public string Password { get; set; }
}        

7. Protect an API Endpoint

Add the [Authorize] attribute to secure the endpoint.

[Authorize]
[HttpGet("profile")]
public async Task<IActionResult> GetProfile()
{
    var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
    return Ok(new { userId });
}        

8. Add Role Based Authorization (Optional but Useful)

Assign roles.

await _roleManager.CreateAsync(new IdentityRole("Admin"));
await _userManager.AddToRoleAsync(user, "Admin");        

Secure controller actions.

[Authorize(Roles = "Admin")]
[HttpGet("admin-data")]
public IActionResult AdminData()
{
    return Ok("Only admin users can access this.");
}        

9. Test the Flow

  1. Register a user.
  2. Log in and receive a token.
  3. Send the token in the Authorization header.
  4. Access protected routes.

Header example:

Authorization: Bearer your_jwt_token_here        

Conclusion

Authentication and authorization are essential for protecting any ASP.NET Core application. By using Identity for user management and JWT for secure session handling, you create a system that is both reliable and easy to scale. The process of registering users, validating login credentials, generating tokens, and controlling access through roles ensures that only the right people can reach protected resources. This approach keeps your API secure and easy to maintain.

https://medium.com/@asad072/step-by-step-guide-for-authentication-and-authorization-in-asp-net-core-using-jwt-identity-d1f1e66b5b5e

To view or add a comment, sign in

More articles by Muhammad Asad

Others also viewed

Explore content categories