C#  

JWT Auth in ASP.NET MVC: Secure REST API with C#.NET

Introduction

In this hands-on guide, you’ll learn how to build a RESTful Web API in ASP.NET MVC using C# with JWT (JSON Web Token) Authentication. This is a modern and secure method for handling user authentication and protecting your endpoints.

By the end of this tutorial, you’ll be able to.

  • Generate JWT tokens on login
  • Authenticate API calls using tokens
  • Secure endpoints so only logged-in users can access them

Tools Required

  • Visual Studio 2019/2022
  • .NET Framework (4.7 or later)
  • NuGet Package: System.IdentityModel.Tokens.Jwt

Step 1. Create a New ASP.NET Web API Project

  1. Open Visual Studio
  2. File → New → Project
  3. Select ASP.NET Web Application (.NET Framework)
  4. Name it JwtStudentAPI
  5. Choose the Web API template and click Create

Step 2. Install Required NuGet Package

Open the Package Manager Console and run.

Install-Package System.IdentityModel.Tokens.Jwt

Step 3. Create Student Model

File: Models/Student.cs.

using System;

namespace JwtStudentAPI.Models
{
    public class Student
    {
        public string StudentId { get; set; }
        public string Name { get; set; }
        public DateTime DateOfBirth { get; set; }
        public string ZipCode { get; set; }
        public string Major { get; set; }
    }
}

Step 4. Create Login Model

File: Models/UserCredential.cs.

namespace JwtStudentAPI.Models
{
    public class UserCredential
    {
        public string Username { get; set; }
        public string Password { get; set; }
    }
}

This is a simple model for a login payload.

Step 5. Add Token Generation Logic

File: Controllers/AuthController.cs.

using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using System.Web.Http;
using JwtStudentAPI.Models;
using Microsoft.IdentityModel.Tokens;

namespace JwtStudentAPI.Controllers
{
    public class AuthController : ApiController
    {
        [HttpPost]
        [Route("api/auth/login")]
        public IHttpActionResult Login(UserCredential login)
        {
            if (login.Username == "admin" && login.Password == "pass123")
            {
                var tokenHandler = new JwtSecurityTokenHandler();
                var key = Encoding.ASCII.GetBytes("MySuperSecretKey12345");

                var tokenDescriptor = new SecurityTokenDescriptor
                {
                    Subject = new ClaimsIdentity(new[]
                    {
                        new Claim(ClaimTypes.Name, login.Username)
                    }),
                    Expires = DateTime.UtcNow.AddMinutes(30),
                    SigningCredentials = new SigningCredentials(
                        new SymmetricSecurityKey(key), 
                        SecurityAlgorithms.HmacSha256Signature)
                };

                var token = tokenHandler.CreateToken(tokenDescriptor);
                var tokenString = tokenHandler.WriteToken(token);

                return Ok(new { token = tokenString });
            }

            return Unauthorized();
        }
    }
}

Explanation

  • Validates the hardcoded user (for demo).
  • Generates a JWT using a secret key.
  • Returns the token to the client.

Step 6. Create a Token Validation Handler

File: Handlers/JwtValidationHandler.cs.

using System;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Claims;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using Microsoft.IdentityModel.Tokens;

namespace JwtStudentAPI.Handlers
{
    public class JwtValidationHandler : DelegatingHandler
    {
        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            if (!request.Headers.Contains("Authorization"))
                return await base.SendAsync(request, cancellationToken);

            var token = request.Headers.Authorization?.Parameter;
            if (token == null)
                return request.CreateResponse(HttpStatusCode.Unauthorized, "Missing token");

            var tokenHandler = new JwtSecurityTokenHandler();
            var key = Encoding.ASCII.GetBytes("MySuperSecretKey12345");

            try
            {
                tokenHandler.ValidateToken(token, new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(key),
                    ValidateIssuer = false,
                    ValidateAudience = false
                }, out SecurityToken validatedToken);

                var jwtToken = (JwtSecurityToken)validatedToken;
                var identity = new ClaimsIdentity(jwtToken.Claims, "jwt");
                Thread.CurrentPrincipal = new ClaimsPrincipal(identity);
            }
            catch
            {
                return request.CreateResponse(HttpStatusCode.Unauthorized, "Invalid token");
            }

            return await base.SendAsync(request, cancellationToken);
        }
    }
}

Step 7. Register the JWT Handler

In Global.asax.cs, add this in Application_Start().

GlobalConfiguration.Configuration.MessageHandlers.Add(
    new JwtStudentAPI.Handlers.JwtValidationHandler()
);

Step 8. Create a Protected Student Controller

File: Controllers/StudentController.cs.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
using JwtStudentAPI.Models;

namespace JwtStudentAPI.Controllers
{
    [Authorize]
    public class StudentController : ApiController
    {
        private static List<Student> students = new List<Student>
        {
            new Student
            {
                StudentId = "S201",
                Name = "Arun Kumar",
                DateOfBirth = new DateTime(2000, 5, 15),
                ZipCode = "600001",
                Major = "IT"
            },
            new Student
            {
                StudentId = "S202",
                Name = "Divya S",
                DateOfBirth = new DateTime(2001, 3, 20),
                ZipCode = "641002",
                Major = "ECE"
            }
        };

        [HttpGet]
        [Route("api/student/{id}")]
        public IHttpActionResult Get(string id)
        {
            var student = students.FirstOrDefault(s => s.StudentId.Equals(id, StringComparison.OrdinalIgnoreCase));
            if (student == null)
                return NotFound();

            return Ok(student);
        }
    }
}

Step 9. Test Your API

1. Get Token

  • POST to: http://localhost:[PORT]/api/auth/login
  • Body
    {
      "Username": "admin",
      "Password": "pass123"
    }
    
  • Response
    {
      "token": "eyJhbGciOi..."
    }
    

2. Access Protected API

  • GET to: http://localhost:[PORT]/api/student/S202
  • Header: Authorization: Bearer [token]

Summary

You have now built a complete JWT-authenticated ASP.NET Web API. You’ve learned how to:

  • Generate a JWT token
  • Validate incoming tokens
  • Protect endpoints with [Authorize]

This is a scalable and secure authentication approach widely used in production systems.

Next Steps

  • Store credentials and keys in secure settings (config or environment variables)
  • Implement user registration and token refresh
  • Use HTTPS in all requests
  • Connect to a real database for dynamic user validation

Hands-On Ideas

  • Add role-based access (e.g., Admin vs Student)
  • Track token expiration
  • Add logout functionality
  • Test using Postman and Swagger

Happy coding with secure APIs! 🚀 Please do comment your questions, which can help to learn better!

Happy learning