Dot Net Core Bearer Token With (JWT)

Butter Ngo | 1008 day | 3694


Chào các bạn hôm nay mình sẽ hướng dẫn các bạn kết hợp "JWT Trong Dot Net Core" thì lần trước mình có viết 1 bài về WebAPI, thì bài viết này giúp các bạn công việc "Authorize" web api của bạn. Vậy ở đây "JWT" là gì Link.

Ok và bây giờ chúng ta bắt đầu làm nó.

Step 1: Chúng ta cần phải tạo 1 project với dot net core nếu bạn nào chưa biết cách tạo project với dot net core có thể xem link để tạo. 

Step 2: Install Package "Microsoft.AspNetCore.Authentication.JwtBearer".

Step 3: Chúng ta sẽ tạo ra 1 class account, và 1 class AccountInMemory

Account.cs

namespace DemoJwt.Models
{
    public class Account
    {
        public string Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string UserName { get; set; }
        public string Password { get; set; }
    }
}

AccountInMemory.cs

namespace DemoJwt.Models
{
    using System;
    using System.Collections.Generic;

    public static class AccountInMemory
    {
        public static IList<Account> ArrayAccount = new List<Account>();

        static AccountInMemory()
        {
            ArrayAccount.Add(new Account
            {
                Id = Guid.NewGuid().ToString("n"),
                FirstName = "Butter",
                LastName = "Ngo",
                UserName ="admin",
                Password = "123456"
            });
        }
    }
}

Step 4: Chúng ta sẽ tạo nhựng file như hình vẽ bên dưới.

Implement Jwt In Dot Net Core

 1. TokenProviderOptions.cs 

namespace DemoJwt.Provider
{
    using Microsoft.IdentityModel.Tokens;
    using System;

    public class TokenProviderOptions
    {
        public string Path { get; set; } = "/token"; //line 1

        public TimeSpan Expiration { get; set; } = TimeSpan.FromDays(+1); //line 2

        public SigningCredentials SigningCredentials { get; set; }//line 3
    }
}
  • Line 1: Dùng để config endpoint.
  • Line 2: Dùng để config expired date cho token.
  • Line 3: Dung để config "Credential" nó giống như 1 serect key để decrypt và encrypt Token.

2.TokenProviderMiddleware.cs

namespace DemoJwt.Provider
{
    using DemoJwt.Models;
    using Microsoft.AspNetCore.Http;
    using Microsoft.Extensions.Options;
    using Newtonsoft.Json;
    using System;
    using System.IdentityModel.Tokens.Jwt;
    using System.Security.Claims;
    using System.Threading.Tasks;
    using System.Linq;
    using System.Collections.Generic;

    public class TokenProviderMiddleware
    {
        private readonly RequestDelegate _next;

        private readonly TokenProviderOptions _options;

        public TokenProviderMiddleware(
            RequestDelegate next,
            IOptions<TokenProviderOptions> options)
        {
            _next = next;
            _options = options.Value;
        }

        public Task Invoke(HttpContext context)
        {
            if (!context.Request.Path.Equals(_options.Path, StringComparison.Ordinal))
            {
                return _next(context);
            }

            if (!context.Request.Method.Equals("POST")
               || !context.Request.HasFormContentType)
            {
                context.Response.StatusCode = 400;
                return context.Response.WriteAsync("Bad request.");
            }

            return GenerateToken(context);
        }

        private async Task GenerateToken(HttpContext context)
        {
            var username = context.Request.Form["username"];
            var password = context.Request.Form["password"];

            var identity = await GetIdentity(username, password);

            if (identity == null)
            {
                context.Response.StatusCode = 400;
                await context.Response.WriteAsync("Invalid username or password.");
                return;
            }

            var now = DateTime.UtcNow;

            var jwt = new JwtSecurityToken(
                claims: identity.Claims,
                notBefore: now,
                expires: now.Add(_options.Expiration),
                signingCredentials: _options.SigningCredentials);

            var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);

            var response = new
            {
                access_token = encodedJwt,
                expires_in = (int)_options.Expiration.TotalSeconds,
            };

            context.Response.ContentType = "application/json";
            await context.Response.WriteAsync(JsonConvert.SerializeObject(response, new JsonSerializerSettings { Formatting = Formatting.Indented }));
        }

        private Task<ClaimsIdentity> GetIdentity(string username, string password)
        {
            var user = AccountInMemory.ArrayAccount.FirstOrDefault(x => x.UserName.Equals(username) && x.Password.Equals(password));

            if (user == null) return null;

            IList<Claim> claims = new List<Claim>();

            claims.Add(new Claim(ClaimTypes.NameIdentifier, user.Id, null, ClaimsIdentity.DefaultIssuer, "Provider"));

            claims.Add(new Claim(ClaimTypes.Name, $"{user.FirstName} {user.LastName}", null, ClaimsIdentity.DefaultIssuer, "Provider"));

            claims.Add(new Claim("Username", user.UserName));

            return Task.FromResult(new ClaimsIdentity(claims, "Bearer"));
        }
    }
}

 Giải thích:

  • Method Invoke: Method này dùng để kiểm tra endpoint nếu nó endpoint == "token" thì chúng ra sẽ xử lý công việc generate token, hoặc bạn có thể xử lý thêm nhựng gì cần thiết vì mỗi request nó đều chạy wa method này, tại sao nó lại chạy qua method này tí nựa mình sẽ giải thich ở phân dưới.
  • Method GenerateToken: Method này dùng để "Verify username and password sau đó generate ra token".
  • Method GetIdentity: Method này dùng dùng để tạo ra claim identiy nếu bạn nào chưa biết về claim identity thì có thể tìm hiểu thêm link.

Step 5: Mở file Startup.cs và add đoạn code sau như hình vẽ bên dưới.

how to implement jwt with dot net core

 public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            string secretKey = "mysite_supersecret_secretkey!8050";//line 1

            SymmetricSecurityKey SigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secretKey));//line 2

            app.UseMiddleware<TokenProviderMiddleware>(Options.Create(new TokenProviderOptions
            {
                SigningCredentials = new SigningCredentials(SigningKey, SecurityAlgorithms.HmacSha256),
            }));//line 3

            app.UseJwtBearerAuthentication(new JwtBearerOptions
            {
                AutomaticAuthenticate = true,
                AutomaticChallenge = true,
                TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = SigningKey,
                    ValidateIssuer = false,
                    ValidateAudience = false,
                }
            });//line 4

            app.UseMvc();
        }
  • Line 1: Đầu tiên mình cần phải tạo ra 1 "Serect Key", key này chúng ta dùng để encrypt và decrypt token.
  • Line 2: SymmetricSecurityKey đầy là 1 class của ms support giúp chúng ta tạo ra 1 SecuretyKey Link.
  • Line 3: Dòng này giúp chúng ta cấu hình "Middleware", thì như ở trên mình đã nói tại sao tất cả các request nó đều di qua hàm invoker, vì hiện tại mình đã customize middleware sử dùng app.UseMiddleware<TokenProviderMiddleware>, và mọi request nó sẽ lun di qua middleware nếu bạn nào muốn tim hiểu thêm về middleware thì có thể access link.
  • Line 4: Dùng để config "Authorize" bằng config jwt.

Ok đến đây coi như mình đã implement done, và bây giờ mình bắt đầu test.

Đầu tiên mình sẽ tạo ra API.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;

namespace DemoJwt.Controllers
{
    [Route("api/[controller]")]
    [Authorize]
    public class ValuesController : Controller
    {
        // GET api/values
        [HttpGet]
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }

        // GET api/values/5
        [HttpGet("{id}")]
        public string Get(int id)
        {
            return "value";
        }

        // POST api/values
        [HttpPost]
        public void Post([FromBody]string value)
        {
        }

        // PUT api/values/5
        [HttpPut("{id}")]
        public void Put(int id, [FromBody]string value)
        {
        }

        // DELETE api/values/5
        [HttpDelete("{id}")]
        public void Delete(int id)
        {
        }
    }
}

tiêp theo mình sẽ làm các bước như hình vẽ bên dưới.

how to implement dot net core with jwt

how to implement dot net core with jwt

Ok vậy là xong, hi vọng bài viết giup ich cho bạn, nếu có chỗ nào không hiểu hay cần giải thích thêm thì cứ comment bên dưới mình sẽ trả lời, và đây là source code


Top Articles

Bất Đầu Với WebApi Và Dot Net Core (.Net Core)

1075 day
Butter Ngo
Views 5996
Comments 0

Repository Và Unit Of Work (Entity Framework)

994 day
ndtung449@gmail.com
Views 3841
Comments 0

Bắt Đầu Với Dot NET Core (.Net Core)

1087 day
Butter Ngo
Views 3576
Comments 0

Dapper Repository & Unit of Work (.Net)

934 day
Tung Nguyen
Views 1965
Comments 0

Top Question

Bi lỗi Invalid Column Name khi sử dụng LinQ (.Net)

935 day
Bảo Dương
Views 957
Answers 2

Làm thế nào để lấy information từ token (.Net Core)

324 day
ngovu.dl@gmail.com
Views 513
Answers 1

.NET CORE API JWT (.Net Core)

228 day
huynhminhnhut97@gmail.com
Views 470
Answers 2