Lädt...

🔧 JWT Authentication & Authorization in ASP.NET


Nachrichtenbereich: 🔧 Programmierung
🔗 Quelle: dev.to

Hey everyone, welcome to our deep dive into JWTs in ASP.NET Core! Whether you’re a beginner or a seasoned developer, this article will guide you through the ins and outs of implementing secure authentication and authorization using JSON Web Tokens (JWT). Grab your favourite beverage, sit back, and let’s get started! 😊

What is JWT

What is JWT? 🔍

JWT stands for JSON Web Token. Think of it as a digital passport that securely transmits information between parties. It’s compact, URL-safe, and self-contained, meaning all the necessary data for authentication is right inside the token. A JWT consists of three key parts:

  • Header:

    Specifies the token type and the hashing algorithm used (e.g., HMAC SHA256).

  • Payload:

    Contains the claims—statements about an entity (usually the user) such as their ID, email, and roles. These claims are essential for both authentication and authorization.

  • Signature:

    Ensures that the token hasn’t been tampered with. It’s created using the header, payload, and a secret key.

You can explore JWTs and see their inner workings at jwt.io 🔗.

Authentication & Authorization

How Does the Authentication & Authorization Process Work? 🛡️

When a client sends a request to a secure API, here’s what happens behind the scenes:

  1. Client Request:

    The client sends a request including the JWT in the Authorization header.

  2. Authentication:

    • The ASP.NET authentication provider extracts the JWT.
    • It validates the token’s signature, expiration, and issuer.
    • If valid, the user is authenticated.
  3. Authorization:

    • The server checks if the user has the required claims to access the resource.
    • If the claims match the required policy, access is granted; otherwise, a 403 Forbidden error is returned.

Policy-Based vs. Role-Based Access Control

Policy-Based vs. Role-Based Access Control 🔐

Role-Based Access Control (RBAC)

  • RBAC assigns roles directly to users.
  • For example, only users with an Admin role might access certain endpoints.
  • This method can become unwieldy as your user base grows.

Policy-Based Access Control

  • Policy-Based access control defines policies (like CanRead) that are assigned to roles.
  • When a user’s role changes, their permissions update automatically without modifying each user individually.
  • This approach is more flexible and scalable, especially for larger applications.

In our demo, we focus on policy-based access control for that extra bit of flexibility!

Implementing JWT in ASP.NET Core: A Step-by-Step Guide 💻

Let’s walk through how to set up JWT authentication in an ASP.NET Core application.

Clone the project

Clone the project from Github and take a look at the authentication and authorisation configuration in the DependencyInjection.cs file:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer();
        services.AddAuthorization();
        services.AddSingleton<IAuthorizationHandler, PermissionAuthorizationHandler>();
        services.AddSingleton<IAuthorizationPolicyProvider, PermissionAuthorizationPolicyProvider>();

We have all authentication configuration in the JwtBearerOptionsSetup file:

internal class JwtBearerOptionsSetup(IOptions<JwtOptions> jwtOptions): IPostConfigureOptions<JwtBearerOptions>
{
    private readonly JwtOptions _jwtOptions = jwtOptions.Value;

    public void PostConfigure(string? name, JwtBearerOptions options)
    {
        options.RequireHttpsMetadata = false;
        options.SaveToken = true;
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidIssuer = _jwtOptions.Issuer,
            ValidateAudience = true,
            ValidAudience = _jwtOptions.Audience,
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtOptions.SecretKey)),
            ValidateLifetime = true,
            ClockSkew = TimeSpan.Zero
        };
    }
}

This setup ensures that every token is validated against your issuer, audience, and signing key.

To add permission authorisation, we have added two files PermissionAuthorizationHandler and PermissionAuthorizationPolicyProvider.

In the PermissionAuthorizationHandler we make sure that the request has enough permission:

public class PermissionAuthorizationHandler : AuthorizationHandler<PermissionRequirement>
{
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement)
    {
        HashSet<string> permissions = context
            .User
            .Claims
            .Where(x => x.Type == Constants.Claims.Permissions)
            .Select(x => x.Value)
            .ToHashSet();

        if (permissions.Contains(requirement.Permission))
        {
            context.Succeed(requirement);
        }

        return Task.CompletedTask;
    }
}

Now, only requests with a valid JWT will be able to access these endpoints.

Another important file is JwtProvider which is responsible for creating the JWT token:

public sealed class JwtProvider(IOptions<JwtOptions> jwtOptions, IPermissionService permissionService) : IJwtProvider
{
    private readonly JwtOptions _jwtOptions = jwtOptions.Value;

    public async Task<string> GenerateJwtTokenAsync(User user)
    {
        List<Claim> claims =
        [
            new(JwtRegisteredClaimNames.Sub, user.Id.ToString()),
            new(JwtRegisteredClaimNames.Email, user.Email!),
            new(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
        ];

        HashSet<string> permissions = await permissionService.GetPermissionsAsync(user.Id);

        claims.AddRange(permissions.Select(permission => new Claim(Constants.Claims.Permissions, permission)));

        SigningCredentials signingCredentials =
            new(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtOptions.SecretKey)), SecurityAlgorithms.HmacSha256);

        JwtSecurityToken token = new(_jwtOptions.Issuer, _jwtOptions.Audience, claims,
            expires: DateTime.UtcNow.AddMinutes(_jwtOptions.TimeoutMinutes), signingCredentials: signingCredentials);

        return new JwtSecurityTokenHandler().WriteToken(token);
    }
}

That's all the configuration we need to know about JWT authentication and authorisation.

Wrap-Up & Key Takeaways 📝

Today, we explored:

  • JWT Fundamentals:

    Understanding JWT as a secure, compact way to transfer claims between parties.

  • Authentication & Authorization Flow:

    From initial user login to token validation and access control.

  • Policy-Based Access Control:

    Offering flexibility over traditional role-based approaches by defining policies like CanRead that are associated with roles.

  • Implementation in ASP.NET Core:

    A step-by-step guide including configuration, creating a login endpoint, and securing your APIs with JWT.

Implementing JWT in your ASP.NET Core applications not only simplifies authentication but also scales beautifully with your growing user base. If you have any questions or feedback, feel free to drop a comment below!

Happy coding! 💻✨

...

🔧 JWT Authentication &amp; Authorization in ASP.NET


📈 39.85 Punkte
🔧 Programmierung

🔧 Custom Role-Based Authorization with JWT in ASP.NET Core


📈 33.07 Punkte
🔧 Programmierung

🔧 ASP.NET Core - REST API Authorization with JWT (Roles vs Claims vs Policy) - Step by Step


📈 33.07 Punkte
🔧 Programmierung

🔧 Issue with User Role-Based Authorization in ASP.NET Core 5 REST API using JWT


📈 33.07 Punkte
🔧 Programmierung

🔧 Share authentication cookies between ASP.NET 4.x and ASP.NET Core


📈 32.17 Punkte
🔧 Programmierung

🕵️ perl-CRYPT-JWT up to 0.022 Access Control JWT.pm _decode_jws() weak authentication


📈 29.96 Punkte
🕵️ Sicherheitslücken

🕵️ Crypt::JWT up to 0.022 on Perl Access Control JWT.pm hmac weak authentication


📈 29.96 Punkte
🕵️ Sicherheitslücken

🕵️ jwt-simple up to 0.3.0 on Node.js jwt.decode weak authentication


📈 29.96 Punkte
🕵️ Sicherheitslücken

🔧 .NET 8.0 Web API 🔒 JWT Authentication and Role-Based Authorization


📈 29.45 Punkte
🔧 Programmierung

🔧 .NET 8.0 Web API 🔒 JWT Authentication and Role-Based Authorization


📈 29.45 Punkte
🔧 Programmierung

🔧 Microsoft .NET Maze: Understand .NET Core Vs .NET Framework Vs ASP.NET


📈 29.06 Punkte
🔧 Programmierung

🔧 Secure Authentication &amp; Authorization in ASP.NET Core 9.0: A Step-by-Step Guide


📈 27.31 Punkte
🔧 Programmierung

🔧 Upcoming SameSite Cookie Changes in ASP.NET and ASP.NET Core


📈 27.29 Punkte
🔧 Programmierung

🔧 Visual Studio for Mac + ASP.NET Core – Getting started with ASP.NET Core using eShopOnWeb


📈 27.29 Punkte
🔧 Programmierung

🔧 Using SkipToken for Paging in Asp.Net OData and Asp.Net Core OData


📈 27.29 Punkte
🔧 Programmierung

🔧 Differences between Asp.net and Asp.net Core


📈 27.29 Punkte
🔧 Programmierung

🔧 Understanding Authentication &amp; Authorization (JWT, OAuth2.0, Session) Concepts


📈 26.2 Punkte
🔧 Programmierung

🔧 JWT in Action: Secure Authentication &amp; Authorization in Go


📈 26.2 Punkte
🔧 Programmierung

🔧 How to manage roles, permissions and more, using jwt token and asp.net core identity


📈 26.18 Punkte
🔧 Programmierung

🔧 Microservices using ASP.NET Core, Ocelot, MongoDB and JWT


📈 26.18 Punkte
🔧 Programmierung

🕵️ Broadboard Instant ASP Message Board reg2.asp Search search.asp txtUserEmail sql injection


📈 25.51 Punkte
🕵️ Sicherheitslücken

🔧 The interplay of authentication and authorization in ASP.NET Core


📈 25.42 Punkte
🔧 Programmierung

🔧 Authentication and Authorization Best Practices in ASP.NET Core


📈 25.42 Punkte
🔧 Programmierung

🔧 ASP.NET 8 - Authentication and Authorization in 7 steps.


📈 25.42 Punkte
🔧 Programmierung

📰 ASP.NET MVC: Using Identity for Authentication and Authorization


📈 25.42 Punkte
📰 IT Security

🕵️ Inversoft prime-jwt JWT Signature Validation erweiterte Rechte


📈 25.08 Punkte
🕵️ Sicherheitslücken

🕵️ jwt-simple bis 0.3.0 jwt.decode schwache Authentisierung


📈 25.08 Punkte
🕵️ Sicherheitslücken

🔧 Without JWT Library Decode and Verify a JWT Token in JavaScript


📈 25.08 Punkte
🔧 Programmierung