JWT 라이센스 시작 -.네트워크 코어 버전

이 블로그 글은 한 사이트에서 JSON 웹 영패 (JWT) 를 발표하는 방법을 가르쳐 줄 것이다.NET Core 3.1 웹 API – 이 설명서도 어느 정도 적용될 수 있습니다.NET 코어 2.2
JWTs는 클라이언트와 서버와 같은 모든 당사자 간에 데이터를 안전하게 전송하는 것을 가능하게 합니다.JWT는 다음 세 부분으로 구성됩니다.
  • 일반적으로 서명 알고리즘과 영패 유형을 정의하는 헤더
  • 유효 로드
  • 는 만료 날짜와 같은 선언 및 사용자 정의 데이터(예: 사용자 UID 및 사용자 유형)를 포함합니다.
  • Base 64 Url 인코딩의 헤더, Base 64 Url 인코딩의 유효한 하중, 키로 구성된 서명
  • JWT의 모양은 다음과 같습니다.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c이것은 기본적으로 다음과 같은 내용으로 바뀔 수 있다.base64urlEncoding(header) + '.' + base64urlEncoding(payload) + '.' + base64urlEncoding(HMAC-SHA256(secret,base64urlEncoding(header) + '.' +base64urlEncoding(payload)))이 JWT는 https://jwt.io/ 에서 왔습니다. 디코딩, 검증, 영패를 생성할 수 있습니다.
    이 안내서에 대해 기본적인 것을 만드셨다고 가정합니다.NET 핵심 웹 API없으면 빈 폴더에 사용합니다dotnet new webapi.
    예시에서 사용한 코드를 찾을 수 있다on GitHub

    필요한 NuGet 패키지 설치
    이 프레젠테이션의 경우 다음 NuGet 패키지를 솔루션에 추가해야 합니다.
  • 마이크로소프트.AspNetCore.인증JWT 로더
  • 마이크로소프트.EntityFrameworkCore.SqlServer

  • 모델 및 승인 속성의 기본 설정
    EF Core를 사용하여 데모를 위해 정보를 데이터베이스에 저장합니다.사용자 모델에 대한 정보는 여기서 확인할 수 있습니다.
        public class User
        {
            [Key]
            public Guid Id { get; set; }
            public string UserName { get; set; }
            public string Password { get; set; }
            public UserType Type { get; set; }
        }
    
        public enum UserType
        {
            Regular = 1,
            Admin = 2,
            SuperUser = 3
        }
    
    이 경우 사용자는 세 가지 유형 중 하나를 가질 수 있다.이러한 유형은 일부 단점을 제한하여 권한을 부여하는 데 사용될 것이다.
    컨트롤러에서 이러한 역할을 수행하려면 다음과 같은 사용자 정의 속성을 만들어야 합니다.
        public class AuthorizeRolesAttribute : AuthorizeAttribute
        {
            public AuthorizeRolesAttribute(params UserType[] roles) : base()
            {
                Roles = string.Join(",", roles);
            }
        }
    
    이렇게 하면 [AuthorizeRoles(UserType.Regular)] 등 AuthorizeRoles 표시를 사용해서만 단점을 특정한 사용자 유형으로 제한할 수 있습니다

    EF 코어 사용
    EF Core를 사용하려면 다음 내용을 appsettings에 추가합니다.발전하다.json.
      "ConnectionStrings": {
        "DefaultConnection": "Server=(localdb)\\MSSQLLocalDB;Integrated Security=true;Database=JwtExample"
      }
    
    이것은 연결할 데이터베이스를 정의합니다.그런 다음 DbContext 클래스를 구현합니다.
        public class JwtExampleContext : DbContext
        {
            public DbSet<User> Users { get; set; }
    
            public JwtExampleContext(DbContextOptions options) : base(options)
            {
            }
    
            protected override void OnModelCreating(ModelBuilder builder)
            {
                builder.Entity<User>()
                    .HasIndex(x => x.UserName)
                    .IsUnique();
    
                var regularUser = new User { Id = Guid.Parse("54D39F1A-EF2D-4816-B2E8-90991F548BF0"), UserName = "Regular", Password = "RegularPassword", Type = UserType.Regular };
                var adminUser = new User { Id = Guid.Parse("36F72591-1D95-4E4F-877C-261D3386DF94"), UserName = "Admin", Password = "AdminPassword", Type = UserType.Admin };
                var superUser = new User { Id = Guid.Parse("FB270C9A-9479-4BD0-9C86-589F3FA84527"), UserName = "Super", Password = "SuperPassword", Type = UserType.SuperUser };
                builder.Entity<User>().HasData(regularUser, adminUser, superUser);
            }
        }
    
    
    데이터베이스에 연결하려면 Startup에 다음 줄을 쓰십시오.대테러 엘리트.
    var connectionString = Configuration.GetConnectionString("DefaultConnection");
    services.AddDbContext<JwtExampleContext>(options => options.UseSqlServer(connectionString));
    
    
    dotnet ef migrations add Initial를 실행하면 마이그레이션 파일이 생성됩니다.및 피드 데이터베이스를 만들려면 dotnet ef database update를 사용하십시오. 이 데이터베이스는 마이그레이션 스크립트를 실행합니다.암호는 명문 형식으로 데이터베이스에 저장해서는 안 된다는 것을 주의하십시오.이것은 단지 시범적인 목적에만 쓰인다.
    컨텍스트가 어떻게 사용되는지 확인하려면 UserRepository를 참조하십시오.대테러 엘리트

    토큰 관련 설정
    먼저 인증과 JWTBear를 추가하도록 IServiceCollection를 구성해야 합니다.이것은 시작할 때 ConfigureServices 에 다음 줄을 추가해서 완성할 수 있습니다.cs 파일은 컴퓨터에 있습니다.NET 핵심 프로젝트:
                var key = Configuration.GetValue<string>("jwt-signing-key");
                services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
                {
                    options.TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidateIssuer = true,
                        ValidateAudience = true,
                        ValidateLifetime = true,
                        ValidateIssuerSigningKey = true,
                        ValidIssuer = "http://localhost:5000",
                        ValidAudience = "http://localhost:5000",
                        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key))
                    };
                });
    
    이 설정들은 반드시 당신의 요구에 적합하지 않을 수도 있고 조정이 필요할 수도 있습니다.키는 appsettings에서 왔습니다.발전하다.json.이 키는 영패에 서명하는 데 사용되며, 시종 비밀로 해야 합니다.
    또한 UseAuthentication()UseAuthorization () 전화를 걸어야 합니다Configure.이러한 방법은 UseRouting() 이후에 사용해야 하지만 UseEndpoints 이전에 사용해야 한다. 이것은 다음과 유사할 것이다.
            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();
                });
            }
    

    토큰을 방출하다
    나는 POST 단점 (api/login) 으로 Login Controller를 만들었다.이 끝점은 사용자 이름과 암호가 포함된 UserdTO를 수락합니다.LoginController에서 토큰을 생성하는 Authentication Service를 호출합니다.AuthenticationService의 방법은 다음과 같습니다.
            public async Task<string> Login(UserDTO user)
            {
                var dbUser = await _repository.GetUser(user.UserName, user.Password);
                var jwt = GenerateJwt(dbUser);
                return jwt;
            }
    
            private string GenerateJwt(User user)
            {
                var key = _configuration.GetValue<string>("jwt-signing-key");
                var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key));
                var signinCredentials = new SigningCredentials(secretKey, SecurityAlgorithms.HmacSha256);
                var tokenOptions = new JwtSecurityToken(
                    issuer: "http://localhost:5000",
                    audience: "http://localhost:5000",
                    claims: new List<Claim>
                    {
                        new Claim(ClaimTypes.NameIdentifier,user.Id.ToString()),
                        new Claim(ClaimTypes.Role,user.Type.ToString()),
                    },
                    expires: DateTime.Now.AddHours(24),
                    signingCredentials: signinCredentials
                );
    
                return new JwtSecurityTokenHandler().WriteToken(tokenOptions);
            }
    
    
    키, 발행인, 시청자와 초창기 회사의 옵션이 일치하는 것은 매우 중요하다.대테러 엘리트.그렇지 않으면, 서명, 발급자, 방문자를 검증하고 있기 때문에 백엔드에서 권한을 부여해야 하는 모든 요청을 금지합니다.
    호출 끝점이 다음과 같이 반환됩니다.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjM2ZjcyNTkxLTFkOTUtNGU0Zi04NzdjLTI2MWQzMzg2ZGY5NCIsImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9jbGFpbXMvcm9sZSI6IkFkbWluIiwiZXhwIjoxNTk4MTk2NzY2LCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjUwMDAiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjUwMDAifQ.x1vksHo5O-Fd8IXCUvEXfxcjToJXc7V7jMS7jqp0h5A
    이렇게!너는 이제 어떻게 기호화폐를 발행하는지 알게 되었다.그러나, 나는 그것을 어떻게 사용하느냐고 물어볼 수도 있다.

    토큰을 사용하다
    사실 간단해!먼저 로그인 자격 증명을 사용하여 api/login을 POST 호출합니다.이것은 이전 절과 같이 영패로 되돌아갈 것이다.이 영패는'Authorization:Bearertoken'라는 HTTP 헤더로 설정해야 합니다.API에 대한 모든 호출에 대해 이 헤더가 있어야 합니다.
    이후 컨트롤러에 새 단점을 만들기만 하면 됩니다.이를 위해 DataController라는 새 컨트롤러를 만들었습니다.이 디렉터의 단점은 다음과 같습니다.
  • api/데이터 얻기 - 권한 필요 없음
  • api/데이터/사용자 가져오기 - 모든 사용자 유형에 적용
  • api/data/admin - 관리자 및 슈퍼유저용 획득
  • api/데이터/수퍼유저 얻기 - 수퍼유저 사용 가능
  • 모든 단점은 작은 인사말과 사용자의user type을 되돌려줍니다.다음 코드 세션은api/data/admin의 실현을 보여 줍니다.
            [AuthorizeRoles(UserType.Admin, UserType.SuperUser)]
            [HttpGet]
            [Route("admin")]
            public IActionResult GetAdminData()
            {
                try
                {
                    var role = User.Claims.First(x => x.Type == ClaimTypes.Role).Value;
                    var text = $"Hello from DataController. Only users above admin can access this endpoint. Your role is {role}.";
                    return Ok(text);
                }
                catch (Exception)
                {
                    return BadRequest();
                }
            }
    
    
    유효한 영패가 없는 상황에서 권한을 부여해야 하는 단점을 호출하면 HTTP 401을 권한이 부여되지 않은 것으로 부른다.라이센스 수준과 일치하지 않는 엔드포인트를 호출하면 HTTP 403이 허용되지 않습니다.
    이렇게!이제 JWTs를 사용하여 권한을 부여하는 방법을 알게 되었습니다.

    그런데 지금은요?
    이 예의 전체 코드에 관심이 있으면 언제든지 저장소here를 보십시오.
    프로젝트를 구축하기 전에 NuGet 패키지를 복구해야 할 수도 있습니다.
    만약 JWT의 업무 방식에 대해 더 많은 관심이 있다면, 방문해 주시기를 강력히 권장합니다. https://jwt.io/
    본문을 읽어 주셔서 감사합니다.나는 네가 그것을 좋아하길 바란다. 아무 질문이나 해라.

    좋은 웹페이지 즐겨찾기