question

6666666 avatar image
0 Votes"
6666666 asked ZhiLv-MSFT answered

Is there a light jwt token in asp.net core web api?

I just want to give a token when user login
and other request I can get the id of the user

I do not want to user identity server that such a big framework.

dotnet-aspnet-core-webapi
· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

AgaveJoe avatar image
1 Vote"
AgaveJoe answered AgaveJoe published

.NET 5 come with a JWT middleware services for validating and creating JWTs. Included below is sample code. See the official reference documentation if you need to learn more about a service or library.

appsettings.json

 {
   "jwtConfig": {
     "Secret": "A super secret string that can be whatever you like"
   },
   "Logging": {
     "LogLevel": {
       "Default": "Information",
       "Microsoft": "Warning",
       "Microsoft.Hosting.Lifetime": "Information"
     }
   }
 }

Configuration

 using JwtService.Services;
 using Microsoft.AspNetCore.Authentication.JwtBearer;
 using Microsoft.AspNetCore.Builder;
 using Microsoft.AspNetCore.Hosting;
 using Microsoft.AspNetCore.HttpsPolicy;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.Hosting;
 using Microsoft.Extensions.Logging;
 using Microsoft.IdentityModel.Tokens;
 using Microsoft.OpenApi.Models;
 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
    
 namespace JwtService
 {
     public class Startup
     {
         public Startup(IConfiguration configuration)
         {
             Configuration = configuration;
         }
    
         public IConfiguration Configuration { get; }
    
         // This method gets called by the runtime. Use this method to add services to the container.
         public void ConfigureServices(IServiceCollection services)
         {
    
             services.AddControllers();
             services.AddSwaggerGen(c =>
             {
                 c.SwaggerDoc("v1", new OpenApiInfo { Title = "JwtService", Version = "v1" });
             });
    
             var secret = Encoding.ASCII.GetBytes(Configuration["JwtConfig:secret"]);
             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(secret),
                     ValidateIssuer = true,
                     ValidateAudience = true,
                     ValidateLifetime = true,
                     ValidIssuer = "Issuer",
                     ValidAudience = "Audience",
                     ClockSkew = TimeSpan.Zero,
                 };
             });
    
             services.AddScoped<IApplicationUser, ApplicationUser>();
         }
    
         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
         public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
         {
             if (env.IsDevelopment())
             {
                 app.UseDeveloperExceptionPage();
                 app.UseSwagger();
                 app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "JwtService v1"));
             }
    
             app.UseHttpsRedirection();
    
             app.UseRouting();
    
             app.UseAuthentication();
             app.UseAuthorization();
    
             app.UseEndpoints(endpoints =>
             {
                 endpoints.MapControllers();
             });
         }
     }
 }

Sample service

     public interface IApplicationUser
     {
         string Authenticate(string username, string password);
         LoginResponse AuthenticateMvc(string username, string password);
     }
    
     public class ApplicationUser : IApplicationUser
     {
         private readonly IConfiguration Configuration;
         public ApplicationUser(IConfiguration configuration)
         {
             Configuration = configuration;
         }
    
         private List<User> _users = new List<User>
         {
             new User { Id = 1, FirstName = "Hello", LastName = "World", Username = "username", Password = "password" }
         };
    
         public string Authenticate(string username, string password)
         {
             var user = _users.SingleOrDefault(x => x.Username == username && x.Password == password);
    
             // return null if user not found
             if (user == null)
                 return null;
    
             // authentication successful so generate jwt token
             var tokenHandler = new JwtSecurityTokenHandler();
             var key = Encoding.ASCII.GetBytes(Configuration["JwtConfig:secret"]);
             var tokenDescriptor = new SecurityTokenDescriptor
             {
                 Subject = new ClaimsIdentity(new Claim[]
                 {
                     new Claim(ClaimTypes.Name, user.Id.ToString()),
                 }),
                 IssuedAt = DateTime.UtcNow,
                 Expires = DateTime.UtcNow.AddDays(7),
                 SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature),
                 Issuer = "Issuer",
                 Audience = "Audience"
             };
             var token = tokenHandler.CreateToken(tokenDescriptor);
             return tokenHandler.WriteToken(token);
         }
    
         public LoginResponse AuthenticateMvc(string username, string password)
         {
             var user = _users.SingleOrDefault(x => x.Username == username && x.Password == password);
    
             // return null if user not found
             if (user == null)
                 return null;
    
             // authentication successful so generate jwt token
             var tokenHandler = new JwtSecurityTokenHandler();
             var key = Encoding.ASCII.GetBytes(Configuration["JwtConfig:secret"]);
             var tokenDescriptor = new SecurityTokenDescriptor
             {
                 Subject = new ClaimsIdentity(new Claim[]
                 {
                     new Claim(ClaimTypes.Name, user.Id.ToString()),
                 }),
                 IssuedAt = DateTime.UtcNow,
                 Expires = DateTime.UtcNow.AddDays(7),
                 SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature),
                 Issuer = "Issuer",
                 Audience = "Audience"
             };
             var token = tokenHandler.CreateToken(tokenDescriptor);
    
             //Mock response
             LoginResponse response = new LoginResponse()
             {
                 token = tokenHandler.WriteToken(token),
                 role = "User",
                 claims = new List<ClaimDto>()
                 {
                     new ClaimDto() {type = ClaimTypes.Role, value = "UserRole" },
                     new ClaimDto() {type= ClaimTypes.Email, value = "email@email.com" }
                 }
             };
    
             return response;
    
         }
     }


Controller
[Authorize]
[ApiController]
[Route("[controller]")]
public class AccountController : ControllerBase
{
private readonly IApplicationUser _authService;
private readonly ILogger<AccountController> _logger;
public AccountController(IApplicationUser authSerice, ILogger<AccountController> logger)
{
_authService = authSerice;
_logger = logger;
}

         //POST: /Account/Authenticate
         [AllowAnonymous]
         [HttpPost("authenticate")]
         [ProducesResponseType(200, Type = typeof(string))]
         [ProducesResponseType(400)]
         [ProducesResponseType(404)]
         public IActionResult Authenticate([FromBody] LoginModel model)
         {
             string token = _authService.Authenticate(model.Username, model.Password);
    
             if (string.IsNullOrEmpty(token))
             {
                 return BadRequest(new { message = "Username or password is incorrect" });
             }
             return Ok(token);
         }
    
         //POST: /Account/AuthenticateMvc
         [AllowAnonymous]
         [HttpPost("authenticatemvc")]
         [ProducesResponseType(200, Type = typeof(LoginResponse))]
         [ProducesResponseType(400)]
         [ProducesResponseType(404)]
         public IActionResult AuthenticateMvc([FromBody] LoginModel model)
         {
             LoginResponse result = _authService.AuthenticateMvc(model.Username, model.Password);
    
             if (result == null || string.IsNullOrEmpty(result.token))
             {
                 return BadRequest(new { message = "Username or password is incorrect" });
             }
             return Ok(result);
         }
     }
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

ZhiLv-MSFT avatar image
1 Vote"
ZhiLv-MSFT answered

Hi @65841535,

You could refer the following sample to implement JWT authentication in Asp.net Core application:

  1. In the API application, configure the authentication schema with JWT bearer options.

      public void ConfigureServices(IServiceCollection services)
         {
             services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                    .AddJwtBearer(options =>
                    {
                        options.TokenValidationParameters = new TokenValidationParameters
                        {
                            ValidateIssuer = true,
                            ValidateAudience = true,
                            ValidateLifetime = true,
                            ValidateIssuerSigningKey = true,
                            ValidIssuer = Configuration["Jwt:Issuer"],
                            ValidAudience = Configuration["Jwt:Issuer"],
                            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
                        };
                    }); 
             services.AddControllers();
         }
    
         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
         public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
         {
             if (env.IsDevelopment())
             {
                 app.UseDeveloperExceptionPage();
             }
    
             app.UseHttpsRedirection();
    
             app.UseRouting();
             app.UseAuthentication();
             app.UseAuthorization();
    
             app.UseEndpoints(endpoints =>
             {
                 endpoints.MapControllers();
             });
         }
    

  2. Store JWT values (Such as: issuer, audience, signing key) in appsettings.json file

     {    
         "Jwt": {
           "Key": "ThisismySecretKey",
           "Issuer": "Test.com"
         },
         }   
    

  3. Generate JSON Web Token: Create a Login controller and after valid user, generate the JWT token.

          [Route("api/[controller]")]
             [ApiController]
             public class LoginController : Controller
             {
                 private IConfiguration _config;
    
                 public LoginController(IConfiguration config)
                 {
                     _config = config;
                 }
                 [AllowAnonymous]
                 [HttpPost]
                 public IActionResult Login([FromBody] UserModel login)
                 {
                     IActionResult response = Unauthorized();
                     var user = AuthenticateUser(login);
    
                     if (user != null)
                     {
                         var tokenString = GenerateJSONWebToken(user);
                         response = Ok(new { token = tokenString });
                     }
    
                     return response;
                 }
    
                 private string GenerateJSONWebToken(UserModel userInfo)
                 {
                     var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"]));
                     var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
    
                     var token = new JwtSecurityToken(_config["Jwt:Issuer"],
                       _config["Jwt:Issuer"],
                       null,
                       expires: DateTime.Now.AddMinutes(120),
                       signingCredentials: credentials);
    
                     return new JwtSecurityTokenHandler().WriteToken(token);
                 }
    
                 private UserModel AuthenticateUser(UserModel login)
                 {
                     UserModel user = null;
    
                     //Validate the User Credentials    
                     //Demo Purpose, I have Passed HardCoded User Information    
                     if (login.Username == "Jignesh")
                     {
                         user = new UserModel { Username = "Jignesh Trivedi", EmailAddress = "test.btest@gmail.com" };
                     }
                     return user;
                 }
             }
    

  4. Apply the JWT authentication, add the [Authorize] attribute at the header of the action method.

              // GET: api/<ValuesController>
                 [HttpGet]
                 [Authorize]
                 public IEnumerable<string> Get()
                 {
                     return new string[] { "value1", "value2" };
                 }
    

More detail information, you could refer this link.


If the answer is helpful, please click "Accept Answer" and upvote it.
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

Best Regards,
Dillion



5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.