ASP.Net Core 3.0 에서 JWT 인증 사용 실현
Jwt 에 대한 소 개 는 인터넷 에 많 습 니 다.여 기 는 군말 이 아 닙 니 다.우 리 는 주로 jwt 의 구 조 를 봅 니 다.
JWT 는 주로 세 부분 으로 구성 되 는데 다음 과 같다.
HEADER.PAYLOAD.SIGNATURE
HEADER
은 token 의 메타 데 이 터 를 포함 하 는데 주로 암호 화 알고리즘 과 서명 의 유형 입 니 다.예 를 들 어 아래 의 정보 와 같이 설명 합 니 다.암호 화 된 대상 유형 은 JWT 이 고 암호 화 알고리즘 은 HMAC SHA-256 입 니 다.
{"alg":"HS256","typ":"JWT"}
그리고 BASE 64 인 코딩 을 통 해 token 에 저장 해 야 합 니 다.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Payload
은 주로 성명 정보(clam)를 포함 하 는데 이 성명 들 은 key-value 가 맞 는 데이터 구조 이다.일반적으로 사용자 이름,캐릭터 등 정보,만 료 날짜 등 은 암호 화 되 지 않 았 기 때문에 민감 한 정 보 를 저장 하 는 것 을 권장 하지 않 습 니 다.
{"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name":"admin","exp":1578645536,"iss":"webapi.cn","aud":"WebApi"}
BASE 64 인 코딩 으로 token 에 저장 해 야 합 니 다.
eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiYWRtaW4iLCJleHAiOjE1Nzg2NDU1MzYsImlzcyI6IndlYmFwaS5jbiIsImF1ZCI6IldlYkFwaSJ9
Signature
jwt 는 jws(JSon Web Signature)의 표준 에 맞 게 최종 서명 을 생 성 해 야 합 니 다.인 코딩 된 Header 와 Payload 정 보 를 합 친 다음 HmacSHA 256 과 같은 강력 한 암호 화 알고리즘 을 사용 하여 암호 화 합 니 다.HS256(BASE64(Header).Base64(Payload),secret)
2_akEH40LR2QWekgjm8Tt3lesSbKtDethmJMo_3jpF4
마지막 으로 생 성 된 token 은 다음 과 같 습 니 다.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiYWRtaW4iLCJleHAiOjE1Nzg2NDU1MzYsImlzcyI6IndlYmFwaS5jbiIsImF1ZCI6IldlYkFwaSJ9.2_akEH40LR2QWekgjm8Tt3lesSbKtDethmJMo_3jpF4
개발 환경프레임 워 크:asp.net 3.1
IDE:VS2019
ASP.NET 3.1 Webapi 에서 JWT 인증 사용
명령 행 에서 다음 명령 을 실행 하고 webapix 프로젝트 를 만 듭 니 다.
dotnet new webapi -n Webapi -o WebApi
특히 주의 할 때 3.x 기본 값 은 jwt 의 Microsoft.AspNetCore.Authentication.JwtBearer 라 이브 러 리 가 없 기 때문에 수 동 으로 NuGet Package 를 추가 하고 프로젝트 가 있 는 디 렉 터 리 로 전환 하여.net cli 명령 을 실행 해 야 합 니 다.
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer --version 3.1.0
jwt 를 서명 하거나 검증 할 때 사용 하 는 정 보 를 저장 하기 위해 간단 한 POCO 클래스 를 만 듭 니 다.
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Webapi.Models
{
public class TokenManagement
{
[JsonProperty("secret")]
public string Secret { get; set; }
[JsonProperty("issuer")]
public string Issuer { get; set; }
[JsonProperty("audience")]
public string Audience { get; set; }
[JsonProperty("accessExpiration")]
public int AccessExpiration { get; set; }
[JsonProperty("refreshExpiration")]
public int RefreshExpiration { get; set; }
}
}
그리고 appsettings.Development.json
에 jwt 가 사용 하 는 설정 정 보 를 추가 합 니 다(생 성 환경 이 라면 appsettings.json
에 추가 하면 됩 니 다)
"tokenManagement": {
"secret": "123456",
"issuer": "webapi.cn",
"audience": "WebApi",
"accessExpiration": 30,
"refreshExpiration": 60
}
그리고 startup 류 의 Configure Services 방법 에 설정 정 보 를 추가 합 니 다.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.Configure<TokenManagement>(Configuration.GetSection("tokenManagement"));
var token = Configuration.GetSection("tokenManagement").Get<TokenManagement>();
}
지금까지 저 희 는 기본 적 인 작업 을 마 쳤 습 니 다.다음은 webapi 에 jwt 의 인증 서 비 스 를 주입 하고 미들웨어 파이프 에서 authentication 미들웨어 를 사용 합 니 다.startup 클래스 에서 jwt 인증 서비스의 네 임 스페이스 를 참조 합 니 다.
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
그리고 ConfigureServices
방법 에 다음 과 같은 논 리 를 추가 합 니 다.
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(Encoding.ASCII.GetBytes(token.Secret)),
ValidIssuer = token.Issuer,
ValidAudience = token.Audience,
ValidateIssuer = false,
ValidateAudience = false
};
});
Configure
방법 에서 인증 사용 하기
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
위 에서 JWT 검증 기능 을 완 료 했 으 니 토 큰 발급 논 리 를 추가 해 야 한다.사용자 인증 과 token 발급 을 위 한 컨트롤 러 를 추가 해 야 합 니 다.AuthenticationController
이 라 고 명명 하 는 동시에 요청 한 DTO 류 를 추가 해 야 합 니 다.
public class LoginRequestDTO
{
[Required]
[JsonProperty("username")]
public string Username { get; set; }
[Required]
[JsonProperty("password")]
public string Password { get; set; }
}
[Route("api/[controller]")]
[ApiController]
public class AuthenticationController : ControllerBase
{
[AllowAnonymous]
[HttpPost, Route("requestToken")]
public ActionResult RequestToken([FromBody] LoginRequestDTO request)
{
if (!ModelState.IsValid)
{
return BadRequest("Invalid Request");
}
return Ok();
}
}
현재 위의 컨트롤 러 는 기본 적 인 논리 만 실현 하고 있 습 니 다.다음은 token 을 발급 하 는 서 비 스 를 만들어 구체 적 인 업 무 를 완성 해 야 합 니 다.첫 번 째 단 계 는 저희 가 먼저 대응 하 는 서비스 인 터 페 이 스 를 만 들 고 IAuthenticateService
이 라 고 명명 합 니 다.
public interface IAuthenticateService
{
bool IsAuthenticated(LoginRequestDTO request, out string token);
}
이어서 인터페이스 실현
public class TokenAuthenticationService : IAuthenticateService
{
public bool IsAuthenticated(LoginRequestDTO request, out string token)
{
throw new NotImplementedException();
}
}
Startup
의 ConfigureServices
방법 에 서 비 스 를 등록 합 니 다.
services.AddScoped<IAuthenticateService, TokenAuthenticationService>();
Controller 에 IAuthenticateService 서 비 스 를 주입 하고 action 을 보완 합 니 다.
public class AuthenticationController : ControllerBase
{
private readonly IAuthenticateService _authService;
public AuthenticationController(IAuthenticateService authService)
{
this._authService = authService;
}
[AllowAnonymous]
[HttpPost, Route("requestToken")]
public ActionResult RequestToken([FromBody] LoginRequestDTO request)
{
if (!ModelState.IsValid)
{
return BadRequest("Invalid Request");
}
string token;
if (_authService.IsAuthenticated(request, out token))
{
return Ok(token);
}
return BadRequest("Invalid Request");
}
}
정상 적 인 상황 에서 저 희 는 요청 한 사용자 와 비밀번호 에 따라 사용자 가 합 법 적 인지 검증 하고 데이터 베 이 스 를 연결 하여 데 이 터 를 가 져 와 검증 해 야 합 니 다.저 희 는 편 의 를 위해 모든 요청 한 사용자 가 합 법 적 이 라 고 가정 합 니 다.여기에 사용자 가 관리 하 는 서 비 스 를 따로 추가 하고 IAuthenticateService 라 는 서비스 에 해당 하 는 논 리 를 추가 하지 않 으 며 주로
을 따 랐 다.우선 위 와 마찬가지 로 서비스 인터페이스 IUserService
을 만 듭 니 다.
public interface IUserService
{
bool IsValid(LoginRequestDTO req);
}
IUserService
인터페이스 실현
public class UserService : IUserService
{
// ,
public bool IsValid(LoginRequestDTO req)
{
return true;
}
}
같은 용기 에 등록
services.AddScoped<IUserService, UserService>();
그 다음 에 Token AuthenticationService 가 token 을 발급 하 는 논 리 를 보완 하려 면 먼저 IUserService 와 Token Management 를 주입 한 다음 에 구체 적 인 업무 논 리 를 실현 해 야 한다.이 token 의 생 성 또는 사용 하 는 Jwt 라 이브 러 리 가 제공 하 는 api 는 구체 적 으로 상세 하 게 설명 하지 않 는 다.특히 Token Management 의 주입 은 IOptions 의 인터페이스 형식 으로 주입 되 었 습 니 다.Startpup 에서 기억 하 십 니까?저 희 는 설정 항목 을 통 해 TokenManagement 유형 을 등록 합 니 다.
public class TokenAuthenticationService : IAuthenticateService
{
private readonly IUserService _userService;
private readonly TokenManagement _tokenManagement;
public TokenAuthenticationService(IUserService userService, IOptions<TokenManagement> tokenManagement)
{
_userService = userService;
_tokenManagement = tokenManagement.Value;
}
public bool IsAuthenticated(LoginRequestDTO request, out string token)
{
token = string.Empty;
if (!_userService.IsValid(request))
return false;
var claims = new[]
{
new Claim(ClaimTypes.Name,request.Username)
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_tokenManagement.Secret));
var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var jwtToken = new JwtSecurityToken(_tokenManagement.Issuer, _tokenManagement.Audience, claims, expires: DateTime.Now.AddMinutes(_tokenManagement.AccessExpiration), signingCredentials: credentials);
token = new JwtSecurityTokenHandler().WriteToken(jwtToken);
return true;
}
}
테스트 에 사용 할 API 를 준비 하고 Authorize 특성 을 눌 러 인증 이 필요 함 을 표시 합 니 다!
[ApiController]
[Route("[controller]")]
[Authorize]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
})
.ToArray();
}
}
테스트 검증 을 지원 합 니 다.저 희 는 potman 을 사용 하여 http 요청 을 할 수 있 습 니 다.http 서 비 스 를 먼저 시작 하고 url 을 가 져 올 수 있 습 니 다.먼저 방문 에 권한 이 필요 한 인 터 페 이 스 를 테스트 할 수 있 지만 token 정 보 를 가지 고 있 지 않 습 니 다.되 돌아 오 는 것 은 401 입 니 다.권한 이 없 음 을 표시 합 니 다.다음 에 인증 인 터 페 이 스 를 통 해 token 을 가 져 왔 는데 오류 가 발생 했 습 니 다.조회 해 보 니 HS 256 알고리즘 의 비밀 키 길 이 는 최신 128 비트 이 고 문자 가 최소 16 글자 로 바 뀌 었 습 니 다.이전에 설정 한 비밀 키 는 123456 이 므 로 이상 이 발생 했 습 니 다.
System.ArgumentOutOfRangeException: IDX10603: Decryption failed. Keys tried: 'HS256'. Exceptions caught: '128'. token: '48' (Parameter 'KeySize') at
비밀 키 업데이트
"tokenManagement": {
"secret": "123456123456123456",
"issuer": "webapi.cn",
"audience": "WebApi",
"accessExpiration": 30,
"refreshExpiration": 60
}
다시 요청,token 가 져 오기 성공eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiYWRtaW4iLCJleHAiOjE1Nzg2NDUyMDMsImlzcyI6IndlYmFwaS5jbiIsImF1ZCI6IldlYkFwaSJ9.AehD8WTAnEtklof2OJsvg0U4_o8_SjdxmwUjzAiuI-o
token 을 이전에 요청 한 api 에 가 져 가서 재 테스트 하여 데 이 터 를 성공 적 으로 가 져 왔 습 니 다.
총화
token 의 인증 방식 을 바탕 으로 분포 식/소나무 결합 시스템 을 구축 하 는 것 이 더욱 쉽 습 니 다.어디서 든 생 성 된 token 은 같은 비밀 키 만 있 으 면 어디서 든 서명 검 사 를 할 수 있 습 니 다.
물론 jwt 인증 방식 을 잘 사용 해 야 합 니 다.그리고 다른 안전 세부 사항 도 처리 해 야 합 니 다.예 를 들 어 palyload 에 민감 한 정 보 를 저장 할 수 없고 https 의 암호 화 전송 방식 을 사용 하 는 등 업무 의 실제 수요 에 따라 더욱 안전 하고 보강 할 수 있 습 니 다!
또한 token 을 사용 하면 쿠키 의 제한 에서 벗 어 날 수 있다 는 것 을 발 견 했 기 때문에 JWT 는 모 바 일 앱 개발 의 최 우선 선택 입 니 다!
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
방법: 데이터베이스에서 선택한 날짜를 Calendar 컨트롤에 표시합니다.Calendar 컨트롤은 데이터 연결을 직접 지원하지 않습니다. 즉, 달력을 데이터 원본에 전체적으로 연결하는 것이 아닙니다.대신 코드를 작성하여 필요한 데이터를 가져오면 Day Render 이벤트에서 현재 표시된 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.