ASP.NET Core 3.1 Ocelot 인증 의 실현
클 라 이언 트 가 Ocelot 를 통 해 하류 서 비 스 를 방문 할 때 하류 자원 서버 를 보호 하기 위해 인증 인증 인증 을 할 것 이 며 이 럴 때 Ocelot 에 인증 서 비 스 를 추가 해 야 한다.인증 서 비 스 를 추가 하면 Ocelot 는 인증 키 를 기반 으로 모든 요청 에 접근 할 수 있 는 자원 을 권한 을 부여 합 니 다.사용 자 는 항상 처럼 Startup.cs 에 인증 서 비 스 를 등록 해 야 합 니 다.그러나 가입 할 때마다 하나의 방안(인증 공급 자 키)을 제공 합 니 다.예 를 들 어:
public void ConfigureServices(IServiceCollection services)
{
var authenticationProviderKey = "TestKey";
services.AddAuthentication()
.AddJwtBearer(authenticationProviderKey, x =>
{
});
}
이 Ocelot 인증 프로젝트 예제 에서 TestKey 는 이 프로그램 을 등록 한 다음 에 게 이 트 웨 이 프로젝트 Routes 경로 에 표시 합 니 다.
{
"Routes": [
{
"DownstreamPathTemplate": "/api/customers",
"DownstreamScheme": "http",
"DownstreamHost": "localhost",
"DownstreamPort": 9001,
"UpstreamPathTemplate": "/customers",
"UpstreamHttpMethod": [ "Get" ],
"AuthenticationOptions": {
"AuthenticationProviderKey": "TestKey",
"AllowedScopes": []
}
}
]
}
Ocelot 가 실 행 될 때 Routes.AuthenticationOptions.AuthenticationProvider Key 를 보고 주어진 키 로 등 록 된 인증 공급 자가 있 는 지 확인 합 니 다.존재 하지 않 으 면 Ocelot 가 시작 되 지 않 고 존재 하면 Routes 는 실행 할 때 이 프로그램 을 사용 합 니 다.경로 에 대한 인증 이 진행 되면 Ocelot 는 인증 미들웨어 를 실행 할 때 이와 관련 된 모든 방안 을 호출 합 니 다.인증 요청 에 실패 하면 Ocelot 는 http 상태 코드 401 을 되 돌려 줍 니 다.2.JWT Tokens Bearer 인증
JSon Web Token(JWT)은 인터넷 애플 리 케 이 션 환경 간 성명 을 전달 하기 위 한 JSON 기반 개방 기준(RFC 7519)이다.이 token 은 치밀 하고 안전 하 며 분포 식 사이트 의 단일 로그 인(SSO)장면 에 특히 적합 하도록 설계 되 었 다.JWT 의 성명 은 일반적으로 신분 제공 자 와 서비스 제공 자 간 에 인 증 된 사용자 신분 정 보 를 전달 하여 자원 서버 에서 자원 을 얻 을 수 있 도록 하고 다른 업무 논리 에 필요 한 성명 정 보 를 추가 할 수 있 으 며 이 token 은 인증 에 직접 사용 할 수도 있 고 암호 화 될 수도 있다.
2.1JWT 영패 구조
치밀 한 형식 에서 JSON Web Tokens 는 dot(.)로 구 분 된 세 부분 으로 구성 되 는데 이들 은 Header 헤드,Payload 유효 부하,Signature 서명 이다.따라서 JWT 는 보통 다음 과 같다.xxxxx.yyyy.zzzzz(Header.Payload.Signature).
2.1.1 헤더
레이 블 은 보통 두 부분 으로 구성 된다.토 큰 의 유형,즉 JWT,그리고 사용 하고 있 는 서명 알고리즘,예 를 들 어 HMAC SHA 256 또는 RSA 등 이다.예 를 들 면:
{
"alg": "HS256",
"typ": "JWT"
}
그리고 이 JSON 은 Base64Url 로 인 코딩 돼 JWT 의 첫 부분 을 형성한다.2.1.2 Payload 유효 부하
Payload 부분도 실제 전달 해 야 할 데 이 터 를 저장 하 는 JSON 대상 이다.JWT 는 선택 할 수 있 도록 7 개의 공식 필드 를 규정 했다.
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
JWT 는 기본적으로 암호 화 되 지 않 고 누구나 읽 을 수 있 으 므 로 비밀 정 보 를 이 부분 에 두 지 마 십시오.이 JSON 대상 도 Base64URL 알고리즘 을 사용 하여 문자열 로 변환 해 야 합 니 다.2.1.3 서명
Signature 부분 은 앞 두 부분의 서명 으로 데이터 변경 을 방지 합 니 다.우선 키(secret)를 지정 해 야 합 니 다.이 키 는 서버 에서 만 알 수 있 으 며 사용자 에 게 누설 할 수 없습니다.그리고 Header 에서 지정 한 서명 알고리즘(기본 값 HMAC SHA 256)을 사용 하여 다음 공식 에 따라 서명 을 생 성 합 니 다.
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
서명 은 메시지 가 변경 되 지 않 았 음 을 검증 하 는 데 사 용 됩 니 다.또한 비밀 키 로 서명 한 토 큰 을 사용 한 경우 JWT 의 보 낸 사람 이 자신 이 주장 하 는 사람 인지 검증 할 수 있 습 니 다.세 가 지 를 모두 함께 놓 으 면 출력 은 점 으로 구 분 된 Base 64-URL 문자열 세 개 로 HTML 과 HTTP 환경 에서 쉽게 전달 할 수 있 으 며 XML 기반 표준(예 를 들 어 SAML)보다 더욱 치밀 하 다.이전 헤드 와 유효 부하 인 코딩 을 가지 고 있 으 며 기밀 서명 을 사용 하 는 JWT 를 보 여 줍 니 다.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoid3prNzAzIiwibmJmIjoiMTU5MjE0MzkzNyIsImV4cCI6MTU5MjE0Mzk5OCwiaXNzIjoiYXV0aC5qd3QuY2MiLCJhdWQiOiJkZW5nd3V8MjAyMC82LzE0IDIyOjEyOjE5In0
.4RiwhRy0rQkZjclOFWyTpmW7v0AMaL3aeve1L-eWIz0
사실 일반적으로 사용자 이름과 비밀 번 호 를 보 내 서 token 을 가 져 오 는 것 은 Identity 4 에서 이 루어 집 니 다.인증 사용 자 를 포함 하여 JwtToken 을 생 성 합 니 다.하지만 프로젝트 는 System.Identity Model.Tokens 라 이브 러 리 로 JwtToken 을 생 성 합 니 다.마지막 으로 jwt 토 큰 을 사용자 에 게 되 돌려 줍 니 다.JwtToken 디 코딩 통과 가능https://jwt.io/조회 중 입 니 다.3.프로젝트 프레젠테이션
3.1 PIGateway 프로젝트
이 항목 에 서 는 하위 api 서 비 스 를 보호 하기 위해 인증 을 사용 하고 JwtBearer 인증 을 사용 하여 기본 인증 방안 을 TestKey 로 설정 합 니 다.apptsettings.json 파일 에 인증 키(Secret)와 시청자(Aud)정 보 를 설정 합 니 다.
{
"Audience": {
"Secret": "Y2F0Y2hlciUyMHdvbmclMjBsb3ZlJTIwLm5ldA==",
"Iss": "http://www.c-sharpcorner.com/members/catcher-wong",
"Aud": "Catcher Wong"
}
}
Startup 인증 코드 는 다음 과 같 습 니 다.
public void ConfigureServices(IServiceCollection services)
{
// appsettings.json (Secret) (Aud)
var audienceConfig = Configuration.GetSection("Audience");
//
var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(audienceConfig["Secret"]));
//token
var tokenValidationParameters = new TokenValidationParameters
{
//
ValidateIssuerSigningKey = true,
//
IssuerSigningKey = signingKey,
//
ValidateIssuer = true,
//
ValidIssuer = audienceConfig["Iss"],
//
ValidateAudience = true,
//
ValidAudience = audienceConfig["Aud"],
// Token , Token Claims NotBefore Expires
ValidateLifetime = true,
//
ClockSkew = TimeSpan.Zero,
// Token Claims Expires
RequireExpirationTime = true,
};
// , TestKey
services.AddAuthentication(o =>
{
o.DefaultAuthenticateScheme = "TestKey";
})
.AddJwtBearer("TestKey", x =>
{
x.RequireHttpsMetadata = false;
// JwtBearerOptions ,IssuerSigningKey( )、ValidIssuer(Token )、ValidAudience( ) 。
x.TokenValidationParameters = tokenValidationParameters;
});
// Ocelot , Secret 、Iss 、Aud
services.AddOcelot(Configuration);
}
public async void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
//
app.UseAuthentication();
// Ocelot
await app.UseOcelot();
}
3.1.1 Identity 서버 탑재 JWT 토 큰두 번 째 소절 에서 JWT Token 인증 을 소개 할 때 저 희 는 보통 사용자 이름과 비밀 번 호 를 보 내 Token 을 가 져 오 는 것 이 Identity 4 로 이 루어 진 것 임 을 알 고 있 습 니 다.사용 자 를 검증 하고 JWT Token 을 생 성 하 는 것 을 포함 합 니 다.아 이 덴 티 티 티 서버 가 JWT Token 인증 기능 을 탑재 한 셈 이다.Identity Server 를 사용 하여 Token 을 불 러 오기 위해 서 는 Configure Services 에서 프로젝트(키)를 사용 하여 Identity Server 서 비 스 를 등록 하 십시오.이 동작 을 어떻게 수행 해 야 할 지 모 르 면 Identity Server 문 서 를 찾 아 보 세 요.
public void ConfigureServices(IServiceCollection services)
{
var authenticationProviderKey = "TestKey";
Action<IdentityServerAuthenticationOptions> options = o =>
{
o.Authority = "https://whereyouridentityserverlives.com";
o.ApiName = "api";
o.SupportedTokens = SupportedTokens.Both;
o.ApiSecret = "secret";
};
services.AddAuthentication()
.AddIdentityServerAuthentication(authenticationProviderKey, options);
services.AddOcelot();
}
Identity 4 에 서 는 Authority 파라미터 가 OIDC 서비스 주 소 를 지정 합 니 다.OIDC 는 Issuer,Issuer Signingkey 등 설정 을 자동 으로 발견 할 수 있 습 니 다.o.Audience 와 x.TokenValidationParameters=new TokenValidationParameters{ValidAudience="api"}는 같은 효 과 를 가 집 니 다.3.2 AuthServer 프로젝트
이 서 비 스 는 주로 클 라 이언 트 가 보 호 받 는 자원 서버 를 요청 할 때 인증 후 클 라 이언 트 가 필요 로 하 는 JWT Token 이 생 성 되 고 JWT Token 키 코드 는 다음 과 같 습 니 다.
[Route("api/[controller]")]
public class AuthController : Controller
{
private IOptions<Audience> _settings;
public AuthController(IOptions<Audience> settings)
{
this._settings = settings;
}
/// <summary>
///
///
/// token
/// token, token , headers: {'Authorization': 'Bearer ' + token}
/// token ,
/// </summary>
/// <param name="name"></param>
/// <param name="pwd"></param>
/// <returns></returns>
[HttpGet]
public IActionResult Get(string name, string pwd)
{
//
if (name == "catcher" && pwd == "123")
{
var now = DateTime.UtcNow;
// , ,
var claims = new Claim[]
{
//
new Claim(JwtRegisteredClaimNames.Sub, name),
//JWT ID
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
// issued timestamp
new Claim(JwtRegisteredClaimNames.Iat, now.ToUniversalTime().ToString(), ClaimValueTypes.Integer64)
};
// Microsoft.IdentityModel.Tokens JwtToken
//
var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(_settings.Value.Secret));
// jwt
var tokenValidationParameters = new TokenValidationParameters
{
//
ValidateIssuerSigningKey = true,
//
IssuerSigningKey = signingKey,
//
ValidateIssuer = true,
//
ValidIssuer = _settings.Value.Iss,
//
ValidateAudience = true,
//
ValidAudience = _settings.Value.Aud,
// Token , Token Claims NotBefore Expires
ValidateLifetime = true,
//
ClockSkew = TimeSpan.Zero,
// Token Claims Expires
RequireExpirationTime = true,
};
var jwt = new JwtSecurityToken(
//jwt
issuer: _settings.Value.Iss,
//jwt
audience: _settings.Value.Aud,
//jwt
claims: claims,
notBefore: now,
//jwt
expires: now.Add(TimeSpan.FromMinutes(2)),
// : 、
signingCredentials: new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256)
);
// jwt (json web token)
var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);
var responseJson = new
{
access_token = encodedJwt,
expires_in = (int)TimeSpan.FromMinutes(2).TotalSeconds
};
return Json(responseJson);
}
else
{
return Json("");
}
}
}
public class Audience
{
public string Secret { get; set; }
public string Iss { get; set; }
public string Aud { get; set; }
}
apptsettings.json 파일 에 인증 키(Secret)와 시청자(Aud)정 보 를 설정 합 니 다.
{
"Audience": {
"Secret": "Y2F0Y2hlciUyMHdvbmclMjBsb3ZlJTIwLm5ldA==",
"Iss": "http://www.c-sharpcorner.com/members/catcher-wong",
"Aud": "Catcher Wong"
}
}
3.3 CustomerAPIServices 프로젝트이 프로젝트 는 APIGateway 프로젝트 와 마찬가지 로 하위 api 서 비 스 를 보호 하기 위해 JwtBearer 인증 을 사용 하여 기본 인증 방안 을 TestKey 로 설정 합 니 다.apptsettings.json 파일 에 인증 키(Secret)와 시청자(Aud)정 보 를 설정 합 니 다.
{
"Audience": {
"Secret": "Y2F0Y2hlciUyMHdvbmclMjBsb3ZlJTIwLm5ldA==",
"Iss": "http://www.c-sharpcorner.com/members/catcher-wong",
"Aud": "Catcher Wong"
}
}
Startup 인증 코드 는 다음 과 같 습 니 다.
public void ConfigureServices(IServiceCollection services)
{
// appsettings.json (Secret) (Aud)
var audienceConfig = Configuration.GetSection("Audience");
//
var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(audienceConfig["Secret"]));
//token
var tokenValidationParameters = new TokenValidationParameters
{
//
ValidateIssuerSigningKey = true,
//
IssuerSigningKey = signingKey,
//
ValidateIssuer = true,
//
ValidIssuer = audienceConfig["Iss"],
//
ValidateAudience = true,
//
ValidAudience = audienceConfig["Aud"],
// Token , Token Claims NotBefore Expires
ValidateLifetime = true,
//
ClockSkew = TimeSpan.Zero,
// Token Claims Expires
RequireExpirationTime = true,
};
// , TestKey
services.AddAuthentication(o =>
{
o.DefaultAuthenticateScheme = "TestKey";
})
.AddJwtBearer("TestKey", x =>
{
x.RequireHttpsMetadata = false;
// JwtBearerOptions ,IssuerSigningKey( )、ValidIssuer(Token )、ValidAudience( ) 。
x.TokenValidationParameters = tokenValidationParameters;
});
services.AddMvc();
}
public void Configure(IApplicationBuilder app)
{
//
app.UseAuthentication();
app.UseMvc();
}
customersController 에 인증 이 필요 한 방법 을 추가 합 니 다.인증 이 필요 없 는 방법:
[Route("api/[controller]")]
public class CustomersController : Controller
{
//
[Authorize]
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "Catcher Wong", "James Li" };
}
[HttpGet("{id}")]
public string Get(int id)
{
return $"Catcher Wong - {id}";
}
}
3.4 Client App 프로젝트이 항목 은 클 라 이언 트 가 자원 서버 에 접근 하 는 전체 인증 프로 세 스 테스트 항목 을 모 의 하 는 것 으로 프로그램 메 인 프로그램 에서 다음 과 같은 코드 를 볼 수 있 습 니 다.
class Program
{
static void Main(string[] args)
{
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Clear();
client.BaseAddress = new Uri("http://localhost:9000");
// 1. without access_token will not access the service
// and return 401 .
var resWithoutToken = client.GetAsync("/customers").Result;
Console.WriteLine($"Sending Request to /customers , without token.");
Console.WriteLine($"Result : {resWithoutToken.StatusCode}");
//2. with access_token will access the service
// and return result.
client.DefaultRequestHeaders.Clear();
Console.WriteLine("
Begin Auth....");
var jwt = GetJwt();
Console.WriteLine("End Auth....");
Console.WriteLine($"
Token={jwt}");
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {jwt}");
var resWithToken = client.GetAsync("/customers").Result;
Console.WriteLine($"
Send Request to /customers , with token.");
Console.WriteLine($"Result : {resWithToken.StatusCode}");
Console.WriteLine(resWithToken.Content.ReadAsStringAsync().Result);
//3. visit no auth service
Console.WriteLine("
No Auth Service Here ");
client.DefaultRequestHeaders.Clear();
var res = client.GetAsync("/customers/1").Result;
Console.WriteLine($"Send Request to /customers/1");
Console.WriteLine($"Result : {res.StatusCode}");
Console.WriteLine(res.Content.ReadAsStringAsync().Result);
Console.Read();
}
private static string GetJwt()
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri( "http://localhost:9000");
client.DefaultRequestHeaders.Clear();
var res2 = client.GetAsync("/api/auth?name=catcher&pwd=123").Result;
dynamic jwt = JsonConvert.DeserializeObject(res2.Content.ReadAsStringAsync().Result);
return jwt.access_token;
}
}
프로젝트 실행 테스트 결과 보기:코드 를 결합 하면 클 라 이언 트 가 Ocelot 게 이 트 웨 이 를 통 해 하류 서 비 스 를 방문 하 는 것 을 볼 수 있 습 니 다.http://localhost:9000/api/Customers/Get방법 은 이 방법 이 인증 을 거 쳐 야 처리 결 과 를 되 돌려 주기 때문에 JWT Token 인증 을 하고,Token 이 없 는 것 을 발견 하면 Ocelot 는 http 상태 코드 401 을 되 돌려 접근 을 거부 합 니 다.만약 에 저희 가 GetJwt 방법 을 통 해 AuthServer 서비스 에 로그 인 인증 을 통 해 권한 수여 Token 을 받 은 다음 에 이 자원 서버 인 터 페 이 스 를 방문 하면 처리 결 과 를 되 돌려 주 고 인증 속성 을 추가 하지 않 은http://localhost:9000/api/Customers/Get/{id}방법 을 비교 해 보면 Ocelot 인증 이 성공 했다 는 것 을 알 수 있 습 니 다!
4.총화
이 장 은 데모 프로젝트 와 결합 해 Ocelot 에서 JWT Token 인증 을 어떻게 사용 하 는 지 간단히 소개 하 는 것 이다.사실 정식 환경 에서 Ocelot 는 Identity Server 인증 권한 을 통합 해 야 합 니 다.마찬가지 로 Ocelot 미들웨어 를 다시 쓰 면 configuration.json 의 설정 정 보 를 데이터베이스 나 Redis 에 저장 할 수 있 습 니 다.
참고 문헌:
Ocelot 홈 페이지
ASP.NET Core 3.1 Ocelot 인증 의 실현 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 관련 ASP.NET Core 3.1 Ocelot 인증 내용 은 저희 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 읽 어 주시 기 바 랍 니 다.앞으로 도 많은 응원 부 탁 드 리 겠 습 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
부트스트랩 ASP.NET에서 설정하는 법1) _Layout.cshtml 內 link로 bootstrap 참조 2) Nuget 패키지에서 BootStrap 다운로드 3) 하단 부트스트랩 예제 사이트 참고해서 프로젝트 개발 참고 :...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.