Safe JWT Verification in ASP.NET Core Using Cookie Storage.NET 9

Leave a Comment

JWT (JSON Web Token) authentication in ASP.NET Core can be implemented by storing the token inside an HTTP-only cookie to enhance security. This method blends the stateless and self-contained nature of JWTs with the added protection provided by secure cookie storage.

Why use JWT with cookies?

JWTs are widely used for authentication because they are stateless and carry all the required user data within the token itself. However, saving JWTs in localStorage or sessionStorage makes them vulnerable to XSS (Cross-Site Scripting) attacks. Placing the token in an HTTP-only cookie helps reduce this risk, while still preserving the advantages of JWT-based authentication.

Step 1: Configure JWT Authentication

To begin, configure JWT authentication in your ASP.NET Core application:

var jwtKey = "qwertyuiopasdfghjklzxcvbnm123456";
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = "your-app",
            ValidAudience = "your-app",
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtKey))
        };

        // Read JWT token from cookie
        options.Events = new JwtBearerEvents
        {
            OnMessageReceived = context =>
            {
                if (context.Request.Cookies.ContainsKey("AuthToken"))
                {
                    context.Token = context.Request.Cookies["AuthToken"];
                }
                return Task.CompletedTask;
            }
        };
    });

builder.Services.AddAuthorization();

Step 2: Configure Middleware

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

add the authentication and authorization middleware in your Program.cs:

Step 3: Generate and Store JWT Tokens

Here's our token generation endpoint:

[HttpPost("GenerateAuthToken")]
public IActionResult GenerateAuthToken()
{
    var jwtKey = "qwertyuiopasdfghjklzxcvbnm123456";
    var token = GenerateJwtToken("Test", jwtKey);
    var cookieOptions = new CookieOptions
    {
        HttpOnly = true,     // Prevent JavaScript access
        Secure = true,       // Only send over HTTPS
        SameSite = SameSiteMode.Strict, // Prevent CSRF
        Expires = DateTime.UtcNow.AddHours(1)
    };

    Response.Cookies.Append("AuthToken", token, cookieOptions);

    return Ok(new { message = "Auth Token generated successfully" });
}

public static string GenerateJwtToken(string username, string key)
{
    var tokenHandler = new JwtSecurityTokenHandler();
    var keyBytes = Encoding.UTF8.GetBytes(key);

    var tokenDescriptor = new SecurityTokenDescriptor
    {
        Subject = new ClaimsIdentity(new[]
        {
            new Claim(ClaimTypes.Name, username)
        }),
        Expires = DateTime.UtcNow.AddHours(1),
        Issuer = "your-app",
        Audience = "your-app",
        SigningCredentials = new SigningCredentials(
            new SymmetricSecurityKey(keyBytes),
            SecurityAlgorithms.HmacSha256Signature)
    };

    var token = tokenHandler.CreateToken(tokenDescriptor);
    return tokenHandler.WriteToken(token);
}

Step 4: Protect Endpoints with Authorization

Now we can protect endpoints using the [Authorize] attribute:

[Authorize]
[HttpGet("GetCurrentProfile")]
public IActionResult GetCurrentProfile()
{
    var username = User.Identity?.Name;
    return Ok(new { user = username });
}

Full Example  : 

Here's a complete minimal API example:

var builder = WebApplication.CreateBuilder(args);

// Add services
var jwtKey = "qwertyuiopasdfghjklzxcvbnm123456";
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = "your-app",
            ValidAudience = "your-app",
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtKey))
        };

        options.Events = new JwtBearerEvents
        {
            OnMessageReceived = context =>
            {
                if (context.Request.Cookies.ContainsKey("AuthToken"))
                {
                    context.Token = context.Request.Cookies["AuthToken"];
                }
                return Task.CompletedTask;
            }
        };
    });

builder.Services.AddAuthorization();
builder.Services.AddControllers();

var app = builder.Build();

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

app.MapControllers();

app.Run();

Security Considerations

  1. Key Management: In production, use a more complex key and store it securely (e.g., in Azure Key Vault or AWS Secrets Manager)

  2. Token Expiration: Keep token lifetimes short (1 hour in our example)

  3. Refresh Tokens: Consider implementing a refresh token mechanism for longer sessions

Best ASP.NET Core 10.0 Hosting Recommendation

One of the most important things when choosing a good ASP.NET Core 8.0 hosting is the feature and reliability. HostForLIFE is the leading provider of Windows hosting and affordable ASP.NET Core, their servers are optimized for PHP web applications. The performance and the uptime of the hosting service are excellent and the features of the web hosting plan are even greater than what many hosting providers ask you to pay for. 

At HostForLIFEASP.NET, customers can also experience fast ASP.NET Core hosting. The company invested a lot of money to ensure the best and fastest performance of the datacenters, servers, network and other facilities. Its datacenters are equipped with the top equipments like cooling system, fire detection, high speed Internet connection, and so on. That is why HostForLIFEASP.NET guarantees 99.9% uptime for ASP.NET Core. And the engineers do regular maintenance and monitoring works to assure its Orchard hosting are security and always up.

Previous PostOlder Post Home

0 comments:

Post a Comment