• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

폴더/페이지 접근 권한 관리

20.12.11 08:52 작성 조회수 291

0

안녕하세요. 강사님.  

지난 도움들 진심으로 감사드리며, 잘 안풀리는 부분이 또 있어 도움 요청 드립니다. 

1) 페이지별 접근 권한을 좀 더 세밀하게 하려면 어떻게 할 수 있을까요? 현재는 강의에서 알려주신 방법을 사용중인데, 저는 회원을 7개 등급으로 만들어 놔서 이 방식으로 하려니 조금 불편한 부분이 있습니다. 가령 Prioriry가 숫자로 되어 있으니 몇 이상으로 한다던가 하려면 어떻게 고쳐야 할까요? 

[Authorize(Roles = MemberSiteRole._managerUser + "," + MemberSiteRole._systemUser)]

2) 특정 폴더에 (예 Admin) 통째로 권한을 부여 하려면 어떻게 해야 하나요? Startup.cs 에 아래와 같이 구현하니 작동은 하는데 회원 권한 상관 없이 모두 접근이 되네요.  위 방식으로 특정 권한을 가진 회원들만 특정 폴더에 접근할 수 있게 하려면 어떻게 고쳐야 할지 도움 부탁드립니다. 

services.AddRazorPages(options =>
            {
                options.Conventions.AuthorizeFolder("/Admin");
            });

매번 구찮게 해드려서 죄송합니다. 강사님의 조언들이 큰 도움이 되고 있습니다. 건강 유의하시고 좋은 하루 되세요. 

감사합니다.

답변 3

·

답변을 작성해보세요.

0

별말씀을요, 즐거운 하루 되세요.

0

Justin님의 프로필

Justin

질문자

2020.12.16

와.... 정말 매번 감동입니다. 이렇게까지 자세하게 해 주실줄은.... 

또 열심히 적용하고 익혀보도록 하겠습니다. 날씨가 매우 추워졌는데 건강 유의하시고 좋은 하루되세요

감사합니다 !!!

0

Justin님, 안녕하세요.

✍ 1)번 답입니다.

제가 강의에서는 role 권한에 대해 언급했는데,

claim 권한을 다룰 때가 되었군요.^^

예를 들어주신 내용으로 만들어 보겠습니다. (스압주의)

(1) [Authorize(Policy = "ManagerAuth")]

Authorize에서 파라미터로 Roles 대신 Policy를

사용합니다.

(2) Startup => ConfigureServices에서,

(using Microsoft.AspNetCore.Authorization;

클래스 맨 위에 참조 추가)

services.AddAuthorization(options =>

{

    options.AddPolicy("ManagerAuth", policy =>

        policy.Requirements.Add(new ManagerAuthorizationRequirement(3)));

});

services.AddScoped<IAuthorizationHandler, ManagerAuthorizationHandler>();

policy 요구사항을 위한 요소를 하나 추가합니다.

그 아래에 AddScoped으로 핸들러를 하나 연결해 줍니다.

(3) Project Root에 /Authorization 폴더를 만들고 하위에

ManagerAuthorizationRequirement 클래스를 추가합니다.

using Microsoft.AspNetCore.Authorization;

public class ManagerAuthorizationRequirement : IAuthorizationRequirement

{

    public byte _minRolePriority { get; set; }

    public ManagerAuthorizationRequirement(byte minRolePriority)

    {

        _minRolePriority = minRolePriority;

    }

}

_minRolePriority은 "권한 우선순위 최소값"을 의미합니다.

(4) 같은 /Authorization 폴더에

ManagerAuthorizationHandler 클래스를 추가합니다.

using Microsoft.AspNetCore.Authorization;

public class ManagerAuthorizationHandler : AuthorizationHandler<ManagerAuthorizationRequirement>

{

    private UserManager<ApplicationUser> _userManager;

    private RoleManager<ApplicationRole> _roleManager;

    public ManagerAuthorizationHandler(UserManager<ApplicationUser> userManager

                                        , RoleManager<ApplicationRole> roleManager)

    {

        _userManager = userManager;

        _roleManager = roleManager;

    }

    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,

                                                    ManagerAuthorizationRequirement requirement)

    {

        var userInRolePriority = GetUserInRole(context).GetAwaiter().GetResult();

        if (userInRolePriority >= requirement._minRolePriority)

        {

            context.Succeed(requirement);

        }

        return Task.CompletedTask;

    }

    private async Task<byte> GetUserInRole(AuthorizationHandlerContext context)

    {

        var user = await _userManager.FindByNameAsync(context.User.Identity.Name);

        var userInRoleNames = await _userManager.GetRolesAsync(user);

        var userInRole = await _roleManager.FindByNameAsync(userInRoleNames.FirstOrDefault());

        return userInRole.RolePriority;

    }

}

Authorization 처리를 하는 핸들러를 만들어 연결합니다.

값을 비교해서 _minRolePriority보다 크면 통과되어야 하므로

context.Succeed 메서드를 사용합니다.

(Task.CompletedTask를 리턴한다는 것은 통과하지 못했다는 겁니다.)

여기서 핵심은 GetUserInRole 메서드인데요.

로그인 사용자 아이디(Name)를 받아와서, 그 사용자의 보유권한리스트를

가져옵니다.

그런데 제 강의에 의하면, 모든 사용자는 하나의 권한만 보유하므로

데이터는 하나밖에 없습니다.

그래서 최종적으로 권한 우선순위를 문제없이 리턴합니다.

또한, HandleRequirementAsync 메서드에서

GetUserInRole 메서드를 불러온 다음에

GetAwaiter().GetResult() 체인메서드를 연결해

비동기를 동기로 바꿔주는 것도 확인하세요.

✍ 2)번 답입니다.

가령, "Pages" 하위로 "Access" 폴더가 있다 합시다.

"Access"안에는 Create, Details Razor Pages가 있다면,

"Access" 내부에 PageModel을 상속받는 AccessPageModel 클래스를

하나 추가합니다. (내용은 다음과 같습니다.)

[Authorize(Policy = "AccessAuth")]

public class AccessPageModel : PageModel

Create, Details Razor Pages 비하인드는 이렇게 시작합니다.

public class CreateModel : AccessPageModel

public class DetailsModel : AccessPageModel

이런 식으로 폴더별로 Custom한 PageModel 클래스를 만들어서

사용하시는 것을 추천합니다.

화이팅하세요!