Integrating JWT Authentication in a .NET Core Web API
In today's world of web development, securing your applications is paramount. One of the most effective ways to achieve this is through JWT (JSON Web Token) authentication. In this comprehensive guide, we will explore how to integrate JWT authentication into a .NET Core Web API. We’ll cover everything from basic definitions to actionable code snippets to help you get started.
What is JWT Authentication?
JWT is an open standard (RFC 7519) that defines a compact and self-contained way to securely transmit information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with HMAC algorithm) or a public/private key pair using RSA or ECDSA.
Why Use JWT?
- Stateless: The server does not need to store session information, making it scalable.
- Compact: JWTs are small in size, making them efficient for transmission over HTTP.
- Self-contained: They contain all the necessary information about the user, reducing database lookups.
- Cross-platform: JWT can be used across different platforms and languages.
Use Cases for JWT Authentication
- API Security: Secure your APIs from unauthorized access.
- Single Sign-On (SSO): Enable users to log in once and gain access to multiple applications.
- Mobile Applications: Securely authenticate users in mobile apps without maintaining sessions.
Setting Up Your .NET Core Project
Before we dive into the implementation, let’s set up a new .NET Core Web API project.
Step 1: Create a New Project
Open your terminal and run the following command:
dotnet new webapi -n JwtAuthDemo
cd JwtAuthDemo
Step 2: Add Required NuGet Packages
You will need to install the following NuGet packages:
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
dotnet add package System.IdentityModel.Tokens.Jwt
Configuring JWT Authentication
Step 3: Configure Services
Open the Startup.cs
file and modify the ConfigureServices
method to include JWT authentication:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
var key = Encoding.ASCII.GetBytes("Your_Secret_Key_Here");
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(x =>
{
x.RequireHttpsMetadata = false;
x.SaveToken = true;
x.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false
};
});
}
Step 4: Enable Authentication Middleware
In the Configure
method, add the authentication middleware:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
Creating the Authentication Controller
Step 5: Implement the AuthController
Create a new controller named AuthController.cs
in the Controllers
folder:
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
[Route("api/[controller]")]
[ApiController]
public class AuthController : ControllerBase
{
[HttpPost("login")]
public IActionResult Login([FromBody] UserLogin login)
{
if (login.Username == "test" && login.Password == "password") // Replace with your user validation
{
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes("Your_Secret_Key_Here");
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new Claim[]
{
new Claim(ClaimTypes.Name, login.Username)
}),
Expires = DateTime.UtcNow.AddDays(7),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
return Ok(new { Token = tokenHandler.WriteToken(token) });
}
return Unauthorized();
}
}
public class UserLogin
{
public string Username { get; set; }
public string Password { get; set; }
}
Step 6: Test the API
You can test the login API using tools like Postman or Curl. Send a POST request to https://localhost:{port}/api/auth/login
with a JSON body:
{
"username": "test",
"password": "password"
}
If successful, you will receive a JWT in the response.
Securing Your API Endpoints
Step 7: Apply the [Authorize] Attribute
To secure your API endpoints, you can use the [Authorize]
attribute. For example, create a new controller named ValuesController.cs
:
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
[Authorize]
[HttpGet]
public IActionResult GetValues()
{
return Ok(new string[] { "value1", "value2" });
}
}
Step 8: Testing the Secured Endpoint
To access the secured endpoint, include the token in the Authorization header of your GET request:
Authorization: Bearer <your_JWT_token>
If the token is valid, you will receive the values; otherwise, you will get an unauthorized response.
Conclusion
Integrating JWT authentication in a .NET Core Web API is a powerful way to secure your applications. By following the steps outlined in this guide, you can easily implement JWT authentication, ensuring that your APIs are protected against unauthorized access. As you continue to develop your applications, consider exploring advanced topics such as token expiration, refresh tokens, and user roles to further enhance your security model.