{"id":1463,"date":"2025-06-26T12:55:16","date_gmt":"2025-06-26T12:55:16","guid":{"rendered":"https:\/\/www.cmarix.com\/qanda\/?p=1463"},"modified":"2026-02-05T12:05:47","modified_gmt":"2026-02-05T12:05:47","slug":"how-to-implement-jwt-authentication-in-net-8-apis","status":"publish","type":"post","link":"https:\/\/www.cmarix.com\/qanda\/how-to-implement-jwt-authentication-in-net-8-apis\/","title":{"rendered":"How to Implement JWT Authentication in .NET 8 APIs?"},"content":{"rendered":"\n<p>JWT (JSON Web Token) is a secure, compact means of transmitting identity information between parties as a JSON object, often used for stateless authentication in APIs.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step-by-Step JWT Implementation in .NET 8 API<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">1. Create a New .NET 8 Web API Project<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>dotnet new webapi -n JwtAuthDemo\ncd JwtAuthDemo<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">2. Add NuGet Package<\/h3>\n\n\n\n<p>You may not need to install anything manually since .NET 8 includes JWT libraries, but just in case:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer<\/code><\/pre>\n\n\n\n<p><strong>3. Configure JWT in appsettings.json<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"Jwt\": {\n    \"Key\": \"ThisIsASecretKeyForJWTDoNotShare\", \n    \"Issuer\": \"JwtAuthDemo\",\n    \"Audience\": \"JwtAuthDemoClient\",\n    \"ExpiresInMinutes\": 60\n  },\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Information\",\n      \"Microsoft.AspNetCore\": \"Warning\"\n    }\n  },\n  \"AllowedHosts\": \"*\"\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">4. Create a JWT Token Service<\/h3>\n\n\n\n<p>Create Services\/<a href=\"http:\/\/jwttokenservice.cs\" target=\"_blank\" rel=\"noopener\">JwtTokenService.cs<\/a>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>using System.IdentityModel.Tokens.Jwt;\nusing System.Security.Claims;\nusing System.Text;\nusing Microsoft.Extensions.Options;\nusing Microsoft.IdentityModel.Tokens;\n\npublic class JwtTokenService\n{\n    private readonly IConfiguration _configuration;\n\n    public JwtTokenService(IConfiguration configuration)\n    {\n        _configuration = configuration;\n    }\n\n    public string GenerateToken(string username)\n    {\n        var key = Encoding.UTF8.GetBytes(_configuration&#91;\"Jwt:Key\"]);\n        var issuer = _configuration&#91;\"Jwt:Issuer\"];\n        var audience = _configuration&#91;\"Jwt:Audience\"];\n        var expires = DateTime.UtcNow.AddMinutes(double.Parse(_configuration&#91;\"Jwt:ExpiresInMinutes\"]));\n\n        var claims = new&#91;]\n        {\n            new Claim(JwtRegisteredClaimNames.Sub, username),\n            new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())\n        };\n\n        var token = new JwtSecurityToken(\n            issuer: issuer,\n            audience: audience,\n            claims: claims,\n            expires: expires,\n            signingCredentials: new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256)\n        );\n\n        return new JwtSecurityTokenHandler().WriteToken(token);\n    }\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">5. Register JWT Authentication in <a href=\"http:\/\/program.cs\" target=\"_blank\" rel=\"noopener\">Program.cs<\/a><\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>var builder = WebApplication.CreateBuilder(args);\n\nbuilder.Services.AddControllers();\nbuilder.Services.AddEndpointsApiExplorer();\nbuilder.Services.AddSwaggerGen();\n\n\/\/ Register JWT service\nbuilder.Services.AddSingleton&lt;JwtTokenService>();\n\n\/\/ Add JWT Authentication\nbuilder.Services.AddAuthentication(\"Bearer\")\n    .AddJwtBearer(\"Bearer\", options =>\n    {\n        var jwt = builder.Configuration.GetSection(\"Jwt\");\n        options.TokenValidationParameters = new TokenValidationParameters\n        {\n            ValidateIssuer = true,\n            ValidateAudience = true,\n            ValidateLifetime = true,\n            ValidateIssuerSigningKey = true,\n            ValidIssuer = jwt&#91;\"Issuer\"],\n            ValidAudience = jwt&#91;\"Audience\"],\n            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwt&#91;\"Key\"]))\n        };\n    });\n\nbuilder.Services.AddAuthorization();\n\nvar app = builder.Build();\n\napp.UseHttpsRedirection();\n\napp.UseAuthentication(); \/\/ \ud83d\udd10 Must be before UseAuthorization\napp.UseAuthorization();\n\napp.MapControllers();\n\napp.Run();<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">6. Create an Authentication Controller<\/h3>\n\n\n\n<p>Create Controllers\/AuthController.cs:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>using Microsoft.AspNetCore.Mvc;\n\n&#91;ApiController]\n&#91;Route(\"api\/&#91;controller]\")]\npublic class AuthController : ControllerBase\n{\n    private readonly JwtTokenService _jwtService;\n\n    public AuthController(JwtTokenService jwtService)\n    {\n        _jwtService = jwtService;\n    }\n\n    &#91;HttpPost(\"login\")]\n    public IActionResult Login(&#91;FromBody] LoginRequest login)\n    {\n        if (login.Username == \"admin\" &amp;&amp; login.Password == \"password\")\n        {\n            var token = _jwtService.GenerateToken(login.Username);\n            return Ok(new { token });\n        }\n\n        return Unauthorized(\"Invalid credentials\");\n    }\n}\n\npublic record LoginRequest(string Username, string Password);<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">7. Secure an API Endpoint<\/h3>\n\n\n\n<p>Create a secured controller Controllers\/<a href=\"http:\/\/securecontroller.cs\" target=\"_blank\" rel=\"noopener\">SecureController.cs<\/a>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>using Microsoft.AspNetCore.Authorization;\nusing Microsoft.AspNetCore.Mvc;\n&#91;ApiController]\n&#91;Route(\"api\/&#91;controller]\")]\npublic class SecureController : ControllerBase\n{\n    &#91;HttpGet(\"data\")]\n    &#91;Authorize]\n    public IActionResult GetSecureData()\n    {\n        return Ok(new { message = \"You are authorized to access this data!\" });\n    }\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">8. Test with Swagger or Postman<\/h3>\n\n\n\n<p>First, call POST \/api\/auth\/login with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"username\": \"admin\",\n  \"password\": \"password\"\n}<\/code><\/pre>\n\n\n\n<p>Copy the token returned.<\/p>\n\n\n\n<p>Call GET \/api\/secure\/data with <strong>Authorization<\/strong> header:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Authorization: Bearer &lt;your_token_here><\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<strong>:<\/strong><\/h2>\n\n\n\n<p>JWT authentication in .NET 8 lets you securely manage user access in your APIs. You set up a token system that verifies users when they log in and protects specific endpoints from unauthorized access. After logging in, users receive a token, which they must include in future requests to access secure data. This method helps create a simple, secure, and stateless way to handle user authentication.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>JWT (JSON Web Token) is a secure, compact means of transmitting identity information between parties as a JSON object, often used for stateless authentication in APIs. Step-by-Step JWT Implementation in .NET 8 API 1. Create a New .NET 8 Web API Project 2. Add NuGet Package You may not need to install anything manually since [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":1468,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[4,3],"tags":[],"class_list":["post-1463","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dot-net","category-web"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/posts\/1463","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/comments?post=1463"}],"version-history":[{"count":5,"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/posts\/1463\/revisions"}],"predecessor-version":[{"id":1470,"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/posts\/1463\/revisions\/1470"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/media\/1468"}],"wp:attachment":[{"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/media?parent=1463"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/categories?post=1463"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/tags?post=1463"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}