In modern web applications, JWT (JSON Web Token) is a powerful and widely used technique for securing APIs. This guide will walk you through how to implement JWT authentication in an ASP.NET Core MVC project using a practical controller and configuration example.
π§± Prerequisites
- .NET Core SDK installed
- Visual Studio or VS Code
- Basic understanding of ASP.NET Core
- NuGet packages:
Microsoft.AspNetCore.Authentication.JwtBearer
System.IdentityModel.Tokens.Jwt
π― Project Overview
We are building a simple API that:
- Accepts login credentials
- Generates a JWT token if the credentials are correct
- Provides a protected endpoint (TestApi2) accessible only with a valid token
π Step 1: Configure JWT in Startup.cs
π ConfigureServices
β JWT Setup
public void ConfigureServices(IServiceCollection services)
{
string securityKey = "Your256BitSecretKeyWhichNeedsToBe32BytesLong!"; // Must be 32 bytes
var symmetricSecurityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(securityKey));
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateIssuerSigningKey = true,
ValidIssuer = "myshop.com.in",
ValidAudience = "user",
IssuerSigningKey = symmetricSecurityKey
};
});
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
β Key points:
- The securityKey must be 32 bytes when using HMAC SHA-256.
- The token is validated based on Issuer, Audience, and SigningKey.
π Configure
β Middleware
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseAuthentication(); // π Add JWT Authentication middleware
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
β
Important: app.UseAuthentication()
must be called before UseMvc()
.
π¦ Step 2: Create JWT Controller
Hereβs a breakdown of your TestJWTController
.
[HttpPost]
public IActionResult GetToken()
{
string securityKey = "Your256BitSecretKeyWhichNeedsToBe32BytesLong!";
var symmetricSecurityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(securityKey));
var signingCredentials = new SigningCredentials(symmetricSecurityKey, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
issuer: "myshop.com.in",
audience: "user",
expires: DateTime.Now.AddHours(1),
signingCredentials: signingCredentials
);
return Ok(new JwtSecurityTokenHandler().WriteToken(token));
}
π /GetToken
Endpoint
This endpoint generates a JWT token signed with your securityKey
.
The token is valid for 1 hour.
*π§ͺ /Login
Endpoint (Dummy Authentication)
*
[HttpPost]
public string Login([FromBody] LoginModel login)
{
if (login.Username == "sabir" && login.Password == "sabir")
{
return "Success";
}
return "Unauthorized";
}
- Simple login check with hardcoded credentials.
- In a real-world app, validate against a database.
*π /TestApi
β Public Endpoint
*
[HttpPost]
public string TestApi()
{
byte[] key = new byte[16];
using (var rng = new RNGCryptoServiceProvider())
{
rng.GetBytes(key);
}
return Convert.ToBase64String(key);
}
- Generates a 128-bit random key.
- This API is accessible without authentication.
*π /TestApi2
β Protected with [Authorize]
*
[HttpPost]
[Authorize]
public string TestApi2()
{
byte[] key = new byte[16];
using (var rng = new RNGCryptoServiceProvider())
{
rng.GetBytes(key);
}
return "Auth" + Convert.ToBase64String(key);
}
You must send a valid JWT token in the Authorization header to access this.
Example:
Authorization: Bearer <your_token_here>
π¦ LoginModel Class
Used to bind JSON payload during login:
public class LoginModel
{
public string Username { get; set; }
public string Password { get; set; }
}
π§ͺ Testing the Flow
1. Get Token
POST /TestJWT/GetToken
β Returns JWT token
2. Access Unprotected API
POST /TestJWT/TestApi
β Always works
3. Access Protected API
POST /TestJWT/TestApi2 with Header:
Authorization: Bearer
β Returns response only if token is valid
β Final Thoughts
- π JWT is great for securing APIs in stateless applications.
- π« Do not hardcode credentials or secrets in production.
- π‘ Always store JWT secret keys in a secure config like Azure Key Vault or AWS Secrets Manager.
- π¨βπ» Use middleware and services to centralize token handling and validation.
Top comments (0)