https://matteosonoio.it/aspnet-core-authentication-schemes/
인증 대권한 부여#
ASP에서는 이미 그 차이를 알고 있을 것입니다.NET Core는 특히 구별이 중요하므로 개념을 새로 고쳐 보겠습니다.나중에 여러분이 예상하지 못했던 방식으로 일이 진행되는 이유를 이해하는 데 도움이 될 것입니다.
그래서 아주 간단하게:
인증은 일반적으로 토큰이 유효한지 확인함으로써 사용자가 자신이 누구인지 확인하는 것입니다.
권한 부여는 특정(인증된) 사용자가 일부 작업을 수행할 수 있는지 여부를 결정하는 프로세스입니다.
나중에 알게 되겠지만, 인증만으로는 ASP에서 웹 앱을 보호하기에 충분하지 않습니다.NET Core는 토큰을 확인하는 것만을 의미하기 때문에(예: 엔드포인트에 인증이 필수인지 실제로 적용하지 않음).
인증 체계
인증부터 시작하겠습니다.ASP에서.NET Core 인증은 인증 체계를 사용하여 이루어집니다.
인증 체계는 기본적으로 사용자 인증을 담당하는 코드 조각입니다.
다양한 방법으로 인증을 구현할 수 있기 때문에 가능한 체계가 많습니다.
애플리케이션이 반드시 하나의 인증 체계로 제한될 필요는 없습니다. 둘 이상을 정의하고 동시에 둘 이상을 사용할 수도 있습니다.
스킴의 예로는 쿠키 인증 스킴이 있으며, 여기서 실제 인증 코드는 다음과 같이 구성됩니다.
요청에서 쿠키를 읽습니다.
유효성 확인;
프레임워크에 사용자가 성공적으로 인증되었음을 증명하는 인증 티켓 제공.
또는 쿠키로 사용자를 인증할 수 없는 경우 스킴 코드가 실패 결과를 반환합니다.
ASP.NET Core 7.0은 다음 두 가지 인증 체계와 함께 제공됩니다.
쿠키 인증 방식
JWT 토큰 인증 제도
이 두 가지 계획은 어느 정도 구성할 수 있지만, 여전히 꽤 설득력이 있습니다.
예를 들어, 쿠키 스킴은 암호화되고 클레임(사용자의 속성)을 포함하는 쿠키를 구축합니다. 이는 쿠키가 커질 수 있기 때문에 피해야 할 것입니다.
작동 방식이 마음에 들지 않거나 요구 사항이 다른 경우(예: 세션 토큰 사용) 사용자 지정 인증 체계를 만들 수 있습니다.
인증 체계에 대한 자세한 내용은 공식 문서의 개요 페이지에서 읽을 수 있습니다.
builder.Services.AddAuthentication()
.AddScheme<SessionTokenAuthenticationSchemeOptions, SessionTokenAuthenticationSchemeHandler>(
"SessionTokens",
opts => {}
);
public class SessionTokenAuthenticationSchemeHandler : AuthenticationHandler<SessionTokenAuthenticationSchemeOptions>
{
public SessionTokenAuthenticationSchemeHandler(
IOptionsMonitor<SessionTokenAuthenticationSchemeOptions> options,
ILoggerFactory logger,
UrlEncoder encoder,
ISystemClock clock) : base(options, logger, encoder, clock)
{
}
protected async override Task<AuthenticateResult> HandleAuthenticateAsync()
{
// Read the token from request headers/cookies
// Check that it's a valid session, depending on your implementation
// If the session is valid, return success:
var claims = new[] { new Claim(ClaimTypes.Name, "Test") };
var principal = new ClaimsPrincipal(new ClaimsIdentity(claims, "Tokens"));
var ticket = new AuthenticationTicket(principal, this.Scheme.Name);
return AuthenticateResult.Success(ticket);
// If the token is missing or the session is invalid, return failure:
// return AuthenticateResult.Fail("Authentication failed");
}
}
요약
다음은 본 내용을 요약한 몇 가지 사례입니다.
핸들러에 실제 인증 코드가 포함된 많은 인증 체계를 정의할 수 있습니다.
기본 인증 체계가 수동 또는 자동으로 설정된 경우...
인증 핸들러는 요청할 때마다 호출됩니다.
실제로 권한 부여를 시행하려면, 사용RequireAuthorization()또는[Require]
이미 활성화된 경우 인증을 선택적으로 비활성화하려면,[AllowAnonymous]
기본 구성표가 설정되지 않은 경우...
인증을 활성화할 때 인증 체계를 명시적으로 선택해야 합니다.[Require(AuthenticationSchemes = "...")]
인증 핸들러는 사용자가 인증을 사용하도록 설정한 경우에만 실행됩니다.
구문을 단순화하고 단순히 사용하기 위해[Authorize]시작 시 기본 권한 부여 정책 정의
builder.Services.AddRazorPages(options =>
{
options.Conventions.AuthorizeFolder("/", "AdminPolicy");
options.Conventions.AllowAnonymousToPage("/Login");
});
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
}).AddCookie(options =>
{
options.LoginPath = "/Login";
options.AccessDeniedPath = "/Login";
options.ExpireTimeSpan = TimeSpan.FromHours(1);
});
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("AdminPolicy", policy => policy.RequireClaim(ClaimTypes.Role, "Admin"));
});
전통적으로 닷넷 웹앱은 인증/인가를 미들웨어가 처리합니다.
이때, 인증 스킴(AuthenticationScheme)이나 인증 정책(AuthorizationPolicy) 의 설정이 필요합니다.
인증 미들웨어는 바디에 담겨진 사용자 정보를 데이터 베이스 자료와 비교하여, 일치하면 사용자를 인증(HttpContext.User 에 ClaimsPrincipal 객체를 설정)하고, 이 정보를 인증 미들웨어(와 필요한 경우, 핸들러)가 사용하게 됩니다.
블레이저 서버는 Asp.Net Core 앱의 인증 방식에 의존하기 때문에, 보통의 경우, 인증과 관련한 흐름은 아래와 같습니다.
request => 인증 미들웨어 => 인가 미들웨어 => 핸들러(액션메서드) => 블레이저 영역 { AuthenticationStateProvider => 컴포넌트 }
보통의 경우, AuthenticationStateProvider의 역할은 인증 미들웨어가 설정한 HttpContext.User 정보를 바탕으로 인증 여부만 컴포넌트에게 전달하는 역할에 머무르는 게 일반적입니다.
var user = _httpContext.User.;
참고로, 보통의 경우라도, 블레이저 서버만의 독특한 scope 문제로, HttpContext.User 를 한번만 확인하는 것이 아니라, 주기적으로 인증 여부를 확인해야 합니다. 이를 위해, 블레이저 서버는 아래의 객체를 제공하는데,
...
public abstract class RevalidatingServerAuthenticationStateProvider
: ServerAuthenticationStateProvider, IDisposable
{
...
캐이캐이딩으로 처리하면, 인증정보는 AuthorizeRouteView 에게 전달되고, 이는 다시 AuthorizeView 컴포넌트에게 전달됩니다. 이 객체는 Authorizing, Authorized, NotAuthorized 의 상태에 따라 UI의 노출 여부를 결정합니다.
즉, AuthorizeRouteView 는 인가 미들웨어와 비슷하고, AuthorizeView 는 상태가 세분화된 AuthorizeAttribute와 비슷하죠.
그리고, 코드로만 판단한다면, Register와 Login 이 구별되고 있지 않는 것 같습니다.
Register는 JWT를 발행하는 것이고, Login 은 (세션 저장소에 있는) JWT에 포함된 사용자 credentials 과 사용자가 폼을 통해 입력한 creditials 를 비교하는 과정입니다.
현재 코드의 Login 은 Register 쪽에 가깝습니다.
만약 사용자의 다른 정보가 id를 기준으로 서버에 저장되어 있다면, pw 를 아무거나 입력해도 성공적으로 로그인이 가능하고, id 를 기준으로 그 정보를 열람할 수 있습니다.