첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
728x90
반응형
728x170

TestProject.zip
다운로드

▶ 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
반응형
그리드형(광고전용)
Posted by icodebroker

댓글을 달아 주세요