[C#/ASP.NET MVC/.NETCORE] AuthorizationHandler<TRequirement, TResource> 클래스 : 리소스 기반 작업 권한 부여하기
C#/ASP.NET MVC 2020. 10. 26. 00:45728x90
반응형
728x170
▶ Models/AccountModel.ca
namespace TestProject.Models
{
/// <summary>
/// 계정 모델
/// </summary>
public class AccountModel
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 사용자 ID - UserID
/// <summary>
/// 사용자 ID
/// </summary>
public string UserID { get; set; }
#endregion
#region 사용자명 - UserName
/// <summary>
/// 사용자명
/// </summary>
public string UserName { get; set; }
#endregion
#region 부서 - Department
/// <summary>
/// 부서
/// </summary>
public string Department { get; set; }
#endregion
}
}
728x90
▶ Handlers/DocumentMethod.cs
namespace TestProject.Handlers
{
/// <summary>
/// 문서 메소드
/// </summary>
public static class DocumentMethod
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region Field
/// <summary>
/// 작성
/// </summary>
public static readonly string Write = "Write";
/// <summary>
/// 수정
/// </summary>
public static readonly string Update = "Update";
#endregion
}
}
300x250
▶ Handlers/DocumentAuthorizationRequirement.cs
using Microsoft.AspNetCore.Authorization.Infrastructure;
namespace TestProject.Handlers
{
/// <summary>
/// 문서 권한 요청
/// </summary>
public static class DocumentAuthorizationRequirement
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 작성 요청 - Write
/// <summary>
/// 작성 요청
/// </summary>
public static OperationAuthorizationRequirement Write => new OperationAuthorizationRequirement
{
Name = DocumentMethod.Write
};
#endregion
#region 수정 요청 - Update
/// <summary>
/// 수정 요청
/// </summary>
public static OperationAuthorizationRequirement Update => new OperationAuthorizationRequirement
{
Name = DocumentMethod.Update
};
#endregion
}
}
▶ Handlers/DocumentAuthorizationHandler.cs
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authorization.Infrastructure;
using System.Threading.Tasks;
using TestProject.Models;
namespace TestProject.Handlers
{
/// <summary>
/// 문서 권한 핸들러
/// </summary>
public class DocumentAuthorizationHandler : AuthorizationHandler<OperationAuthorizationRequirement, AccountModel>
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Protected
#region 요청 처리하기 (비동기) - HandleRequirementAsync(context, requirement, account)
/// <summary>
/// 요청 처리하기 (비동기)
/// </summary>
/// <param name="context">권한 핸들러 컨텍스트</param>
/// <param name="requirement">운영 권한 요청</param>
/// <param name="account">계정</param>
/// <returns>태스크</returns>
protected override Task HandleRequirementAsync
(
AuthorizationHandlerContext context,
OperationAuthorizationRequirement requirement,
AccountModel account
)
{
if(requirement.Name == DocumentMethod.Write)
{
if(context.User.Identity.IsAuthenticated)
{
if(account.Department == "영업팀")
{
if(context.User.HasClaim("SalesLevel", "A"))
{
context.Succeed(requirement);
}
else
{
context.Fail();
}
}
else
{
context.Fail();
}
}
}
else if(requirement.Name == DocumentMethod.Update)
{
if(context.User.Identity.IsAuthenticated)
{
if(account.Department == "기획팀")
{
context.Succeed(requirement);
}
else
{
context.Fail();
}
}
}
return Task.CompletedTask;
}
#endregion
}
}
▶ Startup.cs
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using TestProject.Handlers;
namespace TestProject
{
/// <summary>
/// 시작
/// </summary>
public class Startup
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 서비스 컬렉션 구성하기 - ConfigureServices(services)
/// <summary>
/// 서비스 컬렉션 구성하기
/// </summary>
/// <param name="services">서비스 컬렉션</param>
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication("CookieAuthentication")
.AddCookie
(
"CookieAuthentication",
options =>
{
options.Cookie.Name = "TestProject.Cookie";
options.LoginPath = "/Home/Login";
options.AccessDeniedPath = "/Home/NoAuthorized";
}
);
services.AddScoped<IAuthorizationHandler, DocumentAuthorizationHandler>();
services.AddControllersWithViews();
}
#endregion
#region 구성하기 - Configure(app, environment)
/// <summary>
/// 구성하기
/// </summary>
/// <param name="app">애플리케이션 빌더</param>
/// <param name="environment">웹 호스트 환경</param>
public void Configure(IApplicationBuilder app, IWebHostEnvironment environment)
{
if(environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints
(
endpoints =>
{
endpoints.MapDefaultControllerRoute();
}
);
}
#endregion
}
}
▶ Controllers/DocumentController.cs
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
using TestProject.Handlers;
using TestProject.Models;
namespace TestProject.Controllers
{
/// <summary>
/// 문서 컨트롤러
/// </summary>
public class DocumentController : Controller
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 권한 서비스
/// </summary>
private IAuthorizationService authorizationService;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - DocumentController(authorizationService)
/// <summary>
/// 생성자
/// </summary>
/// <param name="authorizationService">권한 서비스</param>
public DocumentController(IAuthorizationService authorizationService)
{
this.authorizationService = authorizationService;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 작성 페이지 처리하기 - Write()
/// <summary>
/// 작성 페이지 처리하기
/// </summary>
/// <returns>액션 결과 태스크</returns>
public async Task<IActionResult> Write()
{
// 데이터베이스에서 조회한 정보라고 가정한다.
AccountModel account = new AccountModel
{
UserID = "E0001",
UserName = "홍길동",
Department = "영업팀"
};
var result = await this.authorizationService.AuthorizeAsync(User, account, DocumentAuthorizationRequirement.Write);
if(!result.Succeeded)
{
return Forbid();
}
return View();
}
#endregion
#region 수정 페이지 처리하기 - Update()
/// <summary>
/// 수정 페이지 처리하기
/// </summary>
/// <returns>액션 결과 태스크</returns>
public async Task<IActionResult> Update()
{
// 데이터베이스에서 조회한 정보라고 가정한다.
AccountModel account = new AccountModel
{
UserID = "E0001",
UserName = "홍길동",
Department = "영업팀"
};
var result = await this.authorizationService.AuthorizeAsync(User, account, DocumentAuthorizationRequirement.Update);
if(!result.Succeeded)
{
return Forbid();
}
return View();
}
#endregion
}
}
728x90
반응형
그리드형(광고전용)
댓글을 달아 주세요