ASP.NET Core 에서 jwt 인증 의 절차 원 리 를 말 합 니 다.

1.권한 수여 검증 을 신속하게 실현
JWT 가 뭐 예요?JWT 를 왜 써 요?JWT 구성?
이 바 이 두 들 은 직접 찾 을 수 있 으 니,여 기 는 더 이상 군말 하지 않 겠 다.
실제로 JWT 인증 모델 이 토 큰 을 인증 근거 로 사용 하 는 수단 이라는 것 만 알 아야 한다.
포스트 맨 이 Token 을 설치 한 위 치 를 살 펴 보 겠 습 니 다.

그렇다면 어떻게 C\#의 HttpClient 를 사용 하여 JWT 인증 웹 API 를 방문 합 니까?

다음은 ASP.NET Core 프로젝트 를 만 들 고 JWT 인증 기능 을 추가 해 보 겠 습 니 다.
1.1 JWT 서비스 설정 추가
Startup.cs 의 ConfigureServices 방법 에 서 비 스 를 추가 합 니 다.

  //         Bearer Token
   //        using Microsoft.AspNetCore.Authentication.JwtBearer;
   //    JwtBearerDefaults.AuthenticationScheme        "Brearer"
   services.AddAuthentication("Bearer")
    .AddJwtBearer(options =>
    {
     options.TokenValidationParameters = new TokenValidationParameters
     {
      ValidateIssuerSigningKey = true,
      IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("abcdABCD1234abcdABCD1234")), //     Token   

      //        
      ValidateIssuer = true,
      //      
      ValidIssuer = "server", 

      //        
      //      
      ValidateAudience = true,
      ValidAudience = "client007",

      //          
      ValidateLifetime = true,
      //       ,      
      ClockSkew = TimeSpan.FromMinutes(120)
     };
    });
Configure 의 중간 부품 을 수정 하 다

app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();  //     
app.UseAuthorization();
이렇게 간단 합 니 다.상기 설정 을 통 해 요청 에 권한 이 있 는 지 검증 해 야 합 니 다.
1.2 토 큰 수여
발급 하 는 Token,ASP.NET Core 는 저장 되 지 않 습 니 다.
ASP.NET Core 는 Token 인증 을 사용 합 니 다.Token 을 생 성 하 는 코드 를 다른 프로그램의 콘 솔 에 마음대로 두 십시오.키 가 Issuer 와 Audience 가 일치 하면 생 성 된 Token 은 이 ASP.NET Core 에 로그 인 할 수 있 습 니 다.
콘 솔 프로그램 을 마음대로 만들어 Token 을 생 성 할 수 있 고,생 성 된 Token 은 ASP.NET Core 프로그램 에 충분히 로그 인 할 수 있다 는 것 이다.
원인 에 대해 서 는 우리 가 나중에 이야기 하 자.
Program.cs 에 이런 방법 을 추가 합 니 다.

  static void ConsoleToke()
  {

   //       
   var claims = new Claim[]
   {
    new Claim(ClaimTypes.Name, "    "),
    new Claim(JwtRegisteredClaimNames.Email, "[email protected]"),
   };

   //   Startup       
   SymmetricSecurityKey key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("abcdABCD1234abcdABCD1234"));

   JwtSecurityToken token = new JwtSecurityToken(
    issuer: "server",
    audience: "client007",
    claims: claims,
    notBefore: DateTime.Now,
    expires: DateTime.Now.AddMinutes(30),
    signingCredentials: new SigningCredentials(key, SecurityAlgorithms.HmacSha256)
   );

   string jwtToken = new JwtSecurityTokenHandler().WriteToken(token);
   Console.WriteLine(jwtToken);
  }
Main() 에서 이 방법 을 호출 합 니 다.

 public static void Main(string[] args)
  {
   ConsoleToke();
   CreateHostBuilder(args).Build().Run();
  }
1.3 API 접근 추가
API 를 추가 합 니 다.[Authorize] 기능 은 이 Controller 나 Action 을 표시 하 는 데 사 용 됩 니 다.규정 에 맞 는 Token 을 사용 해 야 로그 인 할 수 있 습 니 다.

 [Authorize]
 [Route("api/[controller]")]
 [ApiController]
 public class HomeController : ControllerBase
 {
  public string Get()
  {
   Console.WriteLine(User.Claims.FirstOrDefault(x => x.Type == ClaimTypes.Name));
   return "    ";
  }
 }
그리고 ASP.NET Core 를 시작 하여 Postman 테스트 에 접근 합 니 다.https://localhost/api/home。

401(권한 없 음)상태 코드 를 발견 한 것 은 요청 할 때 토 큰 을 휴대 하지 않 아 API 에 접근 할 수 없 기 때 문 입 니 다.
콘 솔 터미널 에서 생 성 된 Token 코드 를 복사 하여 Postman 에 복사 하고 다시 방문 한 결과 응답 상태 코드 가 200 이 고 응답 이 성 공 했 습 니 다.

ASP.NET Core 자체 jwt 인증 은 대략 이렇다.
그렇다면 ASP.NET Core 내 부 는 어떻게 이 뤄 졌 을 까?또 어떤 특성 이 있 습 니까?어떤 구덩이 가 있 습 니까?내 려 다 보 세 요~
2.권한 수여 인증 미들웨어 탐구
위의 작업 에서 우 리 는 파이프 에 두 개의 중간 부품 을 배치 했다.

app.UseAuthentication();
app.UseAuthorization();
app.UseAuthentication(); 은 ASP.NET Core 에 설 정 된 인증 인증 을 통 해 클 라 이언 트 의 신분 표시(Cookie,Token 등)를 읽 고 분석 해 context.User 에 저장 하 는 역할 을 한다.app.UseAuthorization(); 은 현재 방문 중인 Endpoint(Controller 또는 Action)이 [Authorize] 을 사 용 했 는 지,캐릭터 나 전략 을 설 정 했 는 지 판단 한 다음 쿠키 나 Token 이 유효한 지 검증 하 는 역할 을 한다.
사용 특성 설정 은 인증 을 통 해 접근 할 수 있 으 며,일반적으로 다음 과 같은 경우 가 있 습 니 다.

 //      ,      
 public class AController : ControllerBase
 {
  public string Get() { return "666"; }
 }

 /// <summary>
 ///               
 /// </summary>
 [Authorize]
 public class BController : ControllerBase
 {
  public string Get() { return "666"; }
 }

 public class CController : ControllerBase
 {
  //    Get     
  [Authorize]
  public string Get() { return "666"; }
  public string GetB() { return "666"; }
 }

 /// <summary>
 ///           ,  Get    
 /// </summary>
 [Authorize]
 public class DController : ControllerBase
 {
  [AllowAnonymous]
  public string Get() { return "666"; }
 }
2.1 Token 해석 실현
ASP.NET Core 에 서 는 app.UseAuthentication();app.UseAuthorization(); 의 소스 코드 가 각각 하나의 항목 을 사용 하여 쓰 였 으 며 코드 가 비교적 많다.이 두 중간 부품 의 작용 을 이해 하려 면,우 리 는 그들의 기능 을 수 동 으로 실현 해도 무방 하 다.
분 석 된 Token 은 Claims Principal 대상 으로 이 대상 을 context.User 에 할당 한 다음 API 에서 User 인 스 턴 스 를 사용 하여 사용자 의 정 보 를 얻 을 수 있 습 니 다.
미들웨어 에서 아래 코드 를 사용 하면 클 라 이언 트 가 요청 한 Token 분석 을 가 져 올 수 있 습 니 다.

context.RequestServices.GetRequiredService<IAuthenticationService>().AuthenticateAsync(context, JwtBearerDefaults.AuthenticationScheme);
그렇다면 우 리 는 어떻게 원생 의 Http 요청 에서 손 으로 해석 할 수 있 습 니까?내 가 천천히 분해 하 는 거 봐.
우선 TestMiddleware 파일 을 만 들 고 미들웨어 로 사용 합 니 다.

 public class TestMiddleware
 {
  private readonly RequestDelegate _next;
  jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
  public TestMiddleware(RequestDelegate next)
  {
   _next = next;
  }
  public async Task Invoke(HttpContext context)
  {
   if (context == null)
   {
    throw new ArgumentNullException(nameof(context));
   }

   //         


   //         
   await _next(context);
  }
 }
2.1.1 Http 에서 Token 가 져 오기
다음 코드 는 http 요청 에서 머리의 Token 을 가 져 올 수 있 습 니 다.
물론 클 라 이언 트 가 Token 을 가지 고 있 지 않 을 수도 있 고 결 과 를 null 로 얻 을 수 있 으 며 스스로 판단 을 추가 할 수 있 습 니 다.
코드 영역 에 붙이다.

 string tokenStr = context.Request.Headers["Authorization"].ToString();
Header 의 Authorization 키 는 Breaer {Token} 으로 구 성 된 문자열 입 니 다.
2.1.2 유효 토 큰 인지 판단
Token 을 받 으 면 이 Token 이 유효한 지 판단 해 야 합 니 다.
Authorization 은 Breaer {Token} 으로 구성 되 어 있 기 때문에 앞의 Brear 을 제거 해 야 Token 을 얻 을 수 있 습 니 다.

 /// <summary>
  /// Token           Json Web   
  /// </summary>
  /// <param name="tokenStr"></param>
  /// <returns></returns>
  public bool IsCanReadToken(ref string tokenStr)
  {
   if (string.IsNullOrWhiteSpace(tokenStr) || tokenStr.Length < 7)
    return false;
   if (!tokenStr.Substring(0, 6).Equals(Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerDefaults.AuthenticationScheme))
    return false;
   tokenStr = tokenStr.Substring(7);
   bool isCan = jwtSecurityTokenHandler.CanReadToken(tokenStr);

   return isCan;
  }
Token 을 획득 한 후 JwtSecurityTokenHandler.CanReadToken(tokenStr); 을 통 해 Token 이 협의 규범 에 부합 하 는 지 판단 합 니 다.
아래 판단 을 코드 영역 에 붙 입 니 다.

if (!IsCanReadToken(ref tokenStr))
    return ;
2.1.3 해석 토 큰
다음 코드 는 Header 의 Authorization 내용 을 JwtSecurity Token 대상 으로 바 꿀 수 있 습 니 다.
(문자열 을 자 르 는 방식 은 여러 가지 가 있 습 니 다.좋아 하 는 대로...)

 /// <summary>
  ///  Token   JwtSecurityToken,JwtSecurityToken : SecurityToken
  /// </summary>
  /// <param name="tokenStr"></param>
  /// <returns></returns>
  public JwtSecurityToken GetJwtSecurityToken(string tokenStr)
  {
   var jwt = jwtSecurityTokenHandler.ReadJwtToken(tokenStr);
   return jwt;
  }
그러나 이 GetJwtSecurityToken 은 우리 가 주목 하 는 내용 이 아니 라 클 라 임 을 얻 으 려 는 것 이다.
JwtSecurityToken.Claims
아래 코드 를 코드 영역 에 붙 입 니 다.

JwtSecurityToken jst = GetJwtSecurityToken(tokenStr);
IEnumerable<Claim> claims = jst.Claims;
2.1.4 context.User 생 성
context.User 는 Claims Principal 형식 입 니 다.저 희 는 분 석 된 Claim 을 통 해 Claims Principal 을 생 성 합 니 다.

JwtSecurityToken jst = GetJwtSecurityToken(tokenStr);
IEnumerable<Claim> claims = jst.Claims;

List<ClaimsIdentity> ci = new List<ClaimsIdentity>() { new ClaimsIdentity(claims) };
context.User = new ClaimsPrincipal(ci);
최종 코드 블록 은 이 렇 습 니 다.

   //         
   string tokenStr = context.Request.Headers["Authorization"].ToString();
   string requestUrl = context.Request.Path.Value;
   if (!IsCanReadToken(ref tokenStr))
    return;
   JwtSecurityToken jst = GetJwtSecurityToken(tokenStr);
   IEnumerable<Claim> claims = jst.Claims;
   List<ClaimsIdentity> ci = new List<ClaimsIdentity>() { new ClaimsIdentity(claims) };

   context.User = new ClaimsPrincipal(ci);
   var x = new ClaimsPrincipal(ci);
   //         
2.2 검증 인증 실현app.UseAuthentication(); 의 대략적인 실현 과정 은 이미 설명 을 했 고 지금 우 리 는 app.UseAuthorization(); 의 기능 을 계속 실현 할 것 이다.
위의 미들웨어 를 계속 사용 하여 원 코드 블록 구역 에 새로운 영역 을 추가 합 니 다.

//         

//        
 22.2.1 Endpoint
Endpoint 는 http 요청 이 접근 하 는 경로 정보 와 Controller,Action 및 그 특성 등 정 보 를 표시 합 니 다.[Authorize] 특성 은 IAuthorizeData 을 계승 했다.[AllowAnonymous] 특성 은 IAllowAnonymous 을 계승 했다.
다음 코드 는 방문 한 노드 정 보 를 얻 을 수 있 습 니 다.

var endpoint = context.GetEndpoint();
그렇다면 방문 한 Controller 와 Action 이 인증 과 관련 된 특성 을 사 용 했 는 지 어떻게 판단 합 니까?

 var authorizeData = endpoint?.Metadata.GetOrderedMetadata<IAuthorizeData>() ?? Array.Empty<IAuthorizeData>();
메타 데 이 터 는 ASP.NET Core 가 구현 하 는 집합 대상 으로 GetOrderedMetadata<T> 에서 필요 한 특성 정 보 를 찾 아 낼 수 있다.
이 집합 은 contrller 인지 Action 인지 [Authorize] 특성 을 구분 하지 않 는 다.
그렇다면 [AllowAnonymous] 특성 이 있 는 지 판단 해 이렇게 사용 할 수 있다.

if (endpoint?.Metadata.GetMetadata<IAllowAnonymous>() != null)
   {
    await _next(context);
    return;
   }
여기 서 ASP.NET Core 에서 jwt 권한 수여 인증 의 절차 원리 에 관 한 글 을 소개 합 니 다.더 많은 관련 ASP.NET Core jwt 권한 수여 인증 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 바 랍 니 다!

좋은 웹페이지 즐겨찾기