본문 바로가기
ASP.NET Core

ASP.NET Core MVC 6] Authentication VS Authorization

by Fastlane 2022. 1. 14.
728x90
반응형

Authentication

user가 누구인지 확인한다. 

 

Claim

user에 대한 정보조각이다.  claim type과 optional value로 이루어져있다. name-value pair로 정보를 저장한다. 

claim은 어떤 것도 될 수 있다. Name Claim, Email Claim, Role Claim, PhoneNumber Claim 등등...

 

ClaimsIdentity

ClaimsIdentity는 Claims의 collection이다. 

 

ClaimsPrincipal

ClaimsIdentity의 collection이다. 

HttpContext object의 User property로부터 ClaimsPrincipal을 조회할 수 있다.

 

Authentication Handlers

아래 3가지 동작을 한다. 

  • Authenticate a user (AuthenticateAsync() 함수 사용)
  • user가 인증받지 않았으면 login page로 redirect한다. (ChallengeAsync() 함수 사용)
  • user가 인증받았는데, 접속권한이 없으면 Current Request를 Forbid한다. (ForbidAsync() 함수 사용)

AddAuthentication extension method를 사용하여 등록한다. 

builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {
        options.ExpireTimeSpan = TimeSpan.FromMinutes(20);
        options.SlidingExpiration = true;
        options.AccessDeniedPath = "/Forbidden/";
    });

Authentication Scheme

AddAuthentication extension method를 사용하여 등록한 Authentication handler는 새로운 AuthenticationScheme가 된다.

아래의 경우 Cookie Authentication 2번 다른이름으로 등록 되었으므로 3개의 Authentication Schemes를 갖는다.  

services.AddAuthentication()
    .AddJwtBearer("Bearer")
    .AddCookie("Cookies")
    .AddCookie("Cookies2")

Authentication Middleware

Authentication Middleware를 등록한다. HttpContext.User Property를 ClaimsPrincipal과 함께 update할 수 있다. Authentication Handler의 AuthenticateAsync() 함수를 실행하여 ClaimsPrincipal값을 얻는다. 

UseAuthentication() 이후에 오는 middleware는 HttpContext.User Property를 통해서 user를 확인할 수 있다. 

app.UseAuthentication(); //app.UseAuthorization(); 앞에 위치해야 한다. 
app.UseAuthorization();

Authorization

user가 무엇을 할 수 있고, 없는지 확인한다.

[Authorize] attribute, [AllowAnonymous] attribute는 controller, action level에서 사용이 가능하다. 

[Authorize] attribute : 로그인 후에 접속 가능, 로그인 하지 않고 접속 시, 로그인 페이지로 이동

[AllowAnonymous] attribute : 로그인 여부 상관없이 접속 가능

Role based, Claims based, Policy based Authorization이 있다. 

 

역할에 따라 권한 처리를 해야할 때는 Role based (예: User, Admin, Master 등등...)

action에 따라 권한 처리를 해야할 때는 Claims based (예: Create Role, Edit Role, Delete Role 등등...)

Role Based Authorization

[Authorize(Roles = "Admin")]
public class AdminController : Controller
{
}

Role은 Type Role인 Claim이다. 따라서 Policy를 만들어 권한 체크에 사용할 수 있다. 

1) Create Role Policy

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("AdminRolePolicy",
        policy => policy.RequireRole("Admin"));
});

2) Use the Policy for Authorization Checks

[HttpPost]
[Authorize(Policy = "AdminRolePolicy")]
public async Task<IActionResult> DeleteRole(string id)
{
}

Claims Based Authorization

1) Create Claims Policy

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("DeleteRolePolicy",
        policy => policy.RequireClaim("Delete Role"));
});

2) Use the Policy for Authorization Checks

[HttpPost]
[Authorize(Policy = "DeleteRolePolicy")]
public async Task<IActionResult> DeleteRole(string id)
{
}

 

Claims Based Authorization Check in View

@model IEnumerable<IdentityRole>

@using Microsoft.AspNetCore.Authorization

@inject IAuthorizationService IAuthorizationService

@if((await IAuthorizationService.AuthorizeAsync(User, "EditRolePolicy")).Succeeded)
{
    <a class="btn btn-primary" asp-action="EditRole" 
        asp-controller="Admin" asp-route-id="@role.Id">
        Edit
    </a>
}

 

권한이 없으면, /Account/AccessDenied 경로로 이동한다. 

경로를 변경하고 싶으면 아래와 같이 Program.cs 파일에 설정 소스 추가한다. 

builder.Services.ConfigureApplicationCookie(options =>
{
    options.AccessDeniedPath = new PathString("/Admin/AccessDenied");
});

 

AspNetUserClaims 테이블을 보면, ClaimType, ClaimValue 컬럼이 있다. 

아래 Policy는 Edit Role claim만 있으면 충족하지만, 

services.AddAuthorization(options =>
{
    options.AddPolicy("EditRolePolicy",
        policy => policy.RequireClaim("Edit Role"));
});

아래 Policy는 Edit Role claim이 있고, 값이 true여야만 충족이 된다. 

services.AddAuthorization(options =>
{
    options.AddPolicy("EditRolePolicy",
        policy => policy.RequireClaim("Edit Role", "true"));
});

ClaimType : case in-sensitive

ClaimValue : case sensitive

 

 

 

728x90
반응형

댓글