.NET Core Web API Jwt (JSON Web Token) Authentication with ASP.NET identity model

Recently I come across a requirement to create .NET Core Web API using JWT (JSON Web Token) authentication. I have used ASP.NET identity to provide a role-based authentication model. I have used .NET core 3.x to create this example.

For the sake of simplicity, I have used the default .NET Core project template to create a simple project.

First of all, I have created a new project using the ASP.NET Core Web Application template.

.NET Core Web API Jwt (JSON Web Token) Authentication with ASP.NET identity model

Select the project location

.NET Core Web API Jwt (JSON Web Token) Authentication with ASP.NET identity model

Select the project template as “Web Application”. Select Authentication to “Individual user – Store in Application”

.NET Core Web API Jwt (JSON Web Token) Authentication with ASP.NET identity model

Now Visual Studio will create a new project with ASP.NET core identity authentication model. User accounts along with claims are stored in the database. If you run this project you will have the website with login and register functionality.

.NET Core Web API Jwt (JSON Web Token) Authentication with ASP.NET identity model

Now the next step is to create a Web API that uses the same users and generates a unique JWT token for authorization.

Create Login model to use for input parameters for API methods

public class LoginModel
    {

        [Required(ErrorMessage = "Email is required")]
        public string Email { get; set; }

        [Required(ErrorMessage = "Password is required")]
        public string Password { get; set; }
    }

I have created a new controller in the Controllers folder with the name “AuthController” and created a Login method in this controller. The purpose of this method is; when an API client provides a user name and password to the method this method will generate a token. see the following code snippet …

[ApiController]
    [Route("Api/[controller]")]
    public class AuthController : Controller
    {
        public class AuthenticationController : Controller
        {
            private UserManager<IdentityUser> _userManager;

            //private readonly IEmailSender _emailSender; UnComment if you want to add Email Verification also.

            public AuthenticationController(
                UserManager<IdentityUser> userManager)
            {
                _userManager = userManager;

            }

            [HttpPost]
            [Route("Login")]
            public async Task<IActionResult> Login([FromBody] LoginModel model)
            {
                var user = await _userManager.FindByEmailAsync(model.Email);
                if (user != null && await _userManager.CheckPasswordAsync(user, model.Password))
                {
                    var tokenHandler = new JwtSecurityTokenHandler();

                    var tokenDescriptor = new SecurityTokenDescriptor
                    {
                        Subject = new ClaimsIdentity(new Claim[]{
                    new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
                    new Claim(ClaimTypes.Name, user.Email)

                }),
                        Issuer = "https://yourhostname.com",
                        Audience = "https://yourhostname.com",
                        Expires = DateTime.Now.AddDays(1),
                        SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes("Key-From-Appsettings")), SecurityAlgorithms.HmacSha512Signature),
                    };

                    var token = tokenHandler.CreateToken(tokenDescriptor);
                    return Ok(new
                    {
                        token = tokenHandler.WriteToken(token),
                        expiration = token.ValidTo
                    });
                }
                return Unauthorized();
            }

          

        }
    }

Now if you can access this API method through Postman. it will give you Jwt token like below

.NET Core Web API Jwt (JSON Web Token) Authentication with ASP.NET identity model

Now you can use this token to access any secure API controller. An example of a secure controller is below.

[Authorize(AuthenticationSchemes =
        JwtBearerDefaults.AuthenticationScheme, Roles = "ApiUser")]
    [Route("Api/[controller]")]
    [ApiController]
    public class SecureController : ControllerBase
    {
        private readonly UserManager<IdentityUser> _userManager;

        public SecureController(UserManager<IdentityUser> userManager)
        {
            _userManager = userManager;
        }

        [HttpGet]
        [Route("GetUser")]
        public async Task<IActionResult> GetMessageAsync()
        {
            var user = await GetCurrentUserAsync();
            if (user != null)
            {
                return Ok(user);

            }
            return BadRequest("Error");
        }

        #region Helpers
        private async Task<IdentityUser> GetCurrentUserAsync()
        {
            string userName = HttpContext.User.Identity.Name;
            return await _userManager.FindByNameAsync(userName);
        }
        #endregion
    }

The above example controller is only accessed by the user of the role “ApiUser”.

About the author

Naveed Ul-Haq

I'm Naveed. I am a UK based technical architect. I love working with .NET based CMS, eCommerce solutions, .NET Core, DevOps, and Cloud computing. I am a Certified Episerver CMS developer, MCSD (Microsoft Certified Solution Developer) and MCP in Azure application development. I spend my free time with my family and reading books. You can contact me on [email protected]

View all posts

Leave a Reply

Your email address will not be published. Required fields are marked *