0

사용자가 하나 이상의 부서에 할당됩니다.웹 API, 서비스 계층, DB에서 사용자 액세스를 확인하는 더 나은 방법

사용자는 하나 이상의 역할 (예 : )을 가지고 있습니다. 읽기 전용 역할은 자신의 작업 만 볼 수 있습니다. 팀 단원 역할은 다른 사람을보고 편집 할 수 있습니다. 담당 부서 내의 작업이 할당됩니다. 역할이있는 사용자 관리자은 시스템의 모든 작업을보고 편집 할 수 있습니다.

무단 액세스 방지 및 성능상의 이유로 우리는 현재 로그인 한 사용자 아이디를 데이터베이스에 전달하여 액세스 권한이있는 레코드 만 가져올 수 있습니다.

우리의 시스템 설계는 다음과 같습니다

웹 API -> 비즈니스/서비스 레이어 -> 저장소 ->

DB 현재 우리는 각각의 방법에 서비스 계층에 웹 API에서 사용자 ID를 전달하는 곳을 사용자에게 역할이있는 경우를 확인합니다. 팀 구성원 (액세스 권한이있는 부서 내의 다른 사용자 작업을보고 편집 할 수있는 사용자) 및 액세스 권한이있는 모든 부서를 가져온 다음 저장소에 추가로 전달됩니다.

각 메소드에서 사용자 ID를 전달하지 않으려면 더 나은 방법이 있습니까? 위의 디자인에서 사용자의 액세스를 확인하는 가장 좋은 장소는 무엇입니까?

사용자 ID 매개 변수가없는 메소드가 다른 응용 프로그램에서보고하기 위해 동일한 클래스를 사용할 수 있기를 원합니다.

아이디어가 있으십니까?

+0

userId 및 기타 관련 정보를 쿠키로 전달한 다음 userId 및 기타 정보를 확인하는 기본 서비스를 처리 할 수 ​​있습니다. 또한 Attributes를 사용하여 호출이 승인되었는지를 확인할 수 있습니다. 관련 서비스 메소드 위에있는 [ReadOwnRoleRequired]의 예입니다. 현재 코드 예제를 제공 할 수 없으므로 현재로서는 주석으로 남겨 두어야합니다. – NPhillips

+0

방금 ​​"팀 구성원 역할은 다른 부서의 작업을보고 편집 할 수 있습니다. 할당 된 부서 내 작업"을 언급했습니다. 그런 다음 관련 레코드를 얻으려면 사용자 ID를 전달해야합니다. 맞지 않아? –

+0

@NPhillips : 감사합니다. 그러나 사용자 TeamMember는 부서의 다른 사용자의 작업에 액세스 할 수 있습니다.우리는 역할뿐만 아니라 현재 사용자가 액세스 할 수있는 부서를 확인하고이를 db에 전달하여 해당 부서에 대해서만 조회해야합니다. – Iffi

답변

0

사용 의존성 주입 쿼리 및 기타 작업을 수행하는 사용자 ID를 필요로하는 서비스에 일부 ICurrentUser 인스턴스를 주입합니다.

public interface ICurrentUser 
{ 
    int UserId { get; } 
} 

public class AspNetCurrentUser : ICurrentUser 
{ 
    public int UserId { get { return HttpContext.Current.User.GetUserId<int>(); } } 
} 

public class Service : IService 
{ 
    private readonly ICurrentUser _currentUser; 

    public Service(ICurrentUser currentUser) 
    { 
     _currentUser = currentUser; 
    } 

    public object WorkWithUserId() 
    { 
     return _currentUser.UserId; 
    } 
} 
+0

나는 이와 비슷한 것을했다. :) – Iffi

+0

@Iffi 나는 그것을 듣게되어 기쁘다! :) – maxbeaudoin

0

사용자가 요청을 제기 할 수있는 권한이 있는지 확인하는 보안 계층 ​​(서비스 계층 클래스를 꾸미는 클래스로 구성)이 있어야합니다.

예를 들어 웹 API 호출이 ../viewTask/456 인 경우 사용자가 Admin인지, 작업이 속한 부서의 팀 구성원인지 또는 자신의 작업인지 확인하십시오.

데코레이터 클래스는 액세스 제어 검사가 실패 할 경우 승인되지 않은 예외를 전달하거나 올리면 래핑 된 서비스 계층 클래스로 전달됩니다.

뭔가 같은 ...

public class SecuredTaskController : ApiController 
{ 
    private IContext _context; 
    private ITaskService _taskService; 
    // other services needed for access check (eg. userService?) 

    public SecuredTaskController(ITaskService taskService, IContext context 
     // other services needed for access check (eg. userService?) 
     ) 
    { 
     _taskService = taskService; 
     _context = context; 
    } 

    public IHttpActionResult Get(Task task) 
    { 
     if (hasGetAccess(task, _context.UserId)) 
      return Ok(_taskService.Get(task)); 
     else 
      return Unauthorized(); 
    } 

    private bool hasGetAccess(Task task, long userId) 
    { 
     // check if userId has acces to get task 
    } 
} 
+0

예를 보아도 흥미로울 것입니다. Github에 Gist 나 뭔가가 있습니까? – dmcquiggin