2009-11-26 3 views
3

ASP.Net MVC로 시작하겠습니다. 내가 가진 한 가지 질문은 사용자 데이터 보호를위한 모범 사례입니다. 예를 들어 Sales 직원 시나리오에서는 자신의 데이터 만 볼 수 있어야합니다.MVC 사용자 기반 데이터 보안 보호

SalesData/Edit/14 

그들이/또는에 액세스 할 수 없습니다 수있는 다른 데이터를 볼 수 있습니다 "14"로 변경하는 것은 매우 쉽습니다.

이 시점에서 나는 누가 내 로그인했는지 확인하고 요청한 "id"에 대한 액세스 권한이 있는지 확인하기 위해 내 컨트롤러에서 생각하고 있습니다. 이 문제는 응용 프로그램 전체에 적용되는 문제이며이 문제에 접근하는 방법에 대한 모범 사례를 찾고 있습니다. CustomControllers를 볼 수 있을까요? 필터? 또는 무엇을? 이 문제를 다루는 방법에 대한 기사/참고 자료는 감사하겠습니다.

답변

1

현재 로그인 한 사람의 UserID을 매개 변수로 전달할 수있는 방식으로 데이터베이스 리포지토리에서 데이터를 검색하는 방법을 설정하십시오. 그런 다음 사용 권한 테이블을 사용하여 사용자가 액세스 할 수있는 해당 데이터로만 데이터를 필터링 할 수 있습니다.

사용 권한 테이블에는 UserIDContentID이라는 두 개의 필드가 있습니다. 일단 이것이 설정되면 CRUD 화면을 설정하여 관리 권한을 가진 사람이 콘텐츠 권한을 설정할 수 있습니다.

+0

좋습니다. 재 : 권한 테이블, ContentID는 무엇입니까? Orders, OrderItems, SalesSlips 등 ... 많은 엔터티가 있다고 가정 해 보겠습니다. 콘텐츠 란 무엇입니까? ID가 무엇을 매핑했는지 어떻게 알 수 있습니까? – zzz

+0

이 경우 권한 테이블에 TableID 인 다른 필드가 필요합니다. 또한 테이블 이름과 테이블 ID를 포함하는 테이블을 갖는 것이 좋습니다. –

+0

또는 사용자가 액세스 할 수있는 엔티티로 이동하여 해당 레코드를 통합 할 수 있습니다. 예를 들어 영업 사원이 특정 주문에 액세스 할 수있는 경우 해당 주문의 모든 OrderItem에도 액세스 할 수 있습니다. –

0

IPrincipal 및 Authorize (Roles = '...') 특성을 사용하여 동작에 대한 액세스를 제한합니다. 그러면 IPrincipal이 서비스 계층에 주입되고 사용자 IIdentity가 데이터를 필터링하는 데 사용됩니다.

예 : 사용자가 작업을 만듭니다. 모든 사용자는 자신의 작업을 볼 수 있습니다. GetTask (int taskId) 메서드는 먼저 IIdentity의 식별자를 사용하여 CreatedBy 필드로 필터링 한 다음 지정된 id로 작업을 가져옵니다. 사용자가 데이터에 액세스 할 수없는 경우 메소드는 행을 반환하지 않습니다.

1

나는이 함께 볼 수있는 문제는

그런 다음 당신은 그것을 처리하는 일반적인 서비스를 필요 이 응용 폭이 될 것입니다. 어쨌든 IAuthorisationService라고 부릅니다.

나는 이 접근하는 방법에 대한 모범 사례를 찾고 있습니다. CustomControllers에서 을 볼 수 있습니까? 필터? 또는 무엇?

위의 공통 IAuthorisationService를 사용해야합니다.

:

/* Interfaces */ 
public interface IAuthorisationService { 
    bool CanEdit(YourItem item); 
} 

public interface ICurrentUserProvider { 
    YourUserEntity GetCurrentUser(); 
} 

/* Implementations */ 
public class HttpUserProvider : ICurrentUserProvider { 
    public YourUserEntity GetCurrentUser() { 
     return HttpContext.Current.User.Principal as YourUserEntity; 
    } 
} 

public calss RolesAuthorisationService : IAuthorisationService { 
    ICurrentUserProvider userProvider 
    public RolesAuthorisationService(ICurrentUserProvider userProvider) { 
     this.userProvider = userProvider; 
    } 

    public bool CanEdit(YourItem item) { 
     var u = userProvider.GetCurrentUser(); 
     if (u == null) 
      return false; 
     return item.Owner == u && u.IsInRole("EditYourItem"); 
    } 
} 

/* Controller */ 

public class MyController: Controller { 
    IAuthorisationService authorisation; 

    public MyController(IAuthorisationService authorisation) { 
     this.authorisation = authorisation; 
    } 

    public ActionResult Edit(int id) { 
     var item = GetTheItembyIdSomehow(); 
     if (!authorisation.CanEdit(item)) 
      return new HttpUnauthorizedResult(); 

     // Can do this 
    } 
} 

는 그런 다음 컨트롤러에 자동으로 필요한 의존성을 주입 ControllerFactory을 사용할 수 있습니다 : 내 경험에서
나는 그것을 컨트롤러에 서비스를 주입하고 모든 행동에 그것을 사용하기 쉽다는 것을 알 수 있습니다

class DependencyInjectionContainer : WindsorContainer { 
    public DependencyInjectionContainer() { 
     RegisterDependencies(); 
    } 

    private void RegisterDependencies() { 

     // Services 
     Register(
      AllTypes.Of<IDiscoverableService>() 
       .FromAssembly(typeof(IDiscoverableService).Assembly) 
       .Configure(c => c.LifeStyle.Transient) 
       .WithService.FromInterface() 
      ); 

     // Controllers 
     Register(
      AllTypes.Of<IController>() 
       .FromAssembly(typeof(DependencyInjectionContainer).Assembly) 
       .Configure(c => c.LifeStyle.Transient) 
      ); 
    } 
} 

class WindsorControllerFactory : DefaultControllerFactory, IDisposable { 
    private readonly IWindsorContainer container; 

    public WindsorControllerFactory() { 
     container = new DependencyInjectionContainer(); 
    } 

    protected override IController GetControllerInstance(Type controllerType) { 
     if (controllerType == null) 
      return base.GetControllerInstance(controllerType); 
     return (IController) container.Resolve(controllerType); 
    } 

    public void Dispose() { 
     container.Dispose(); 
    } 
} 
+0

코드를 보면 특정 항목에 대한 권한이 아니라 "편집"과 같은 역할 만 지정하는 것처럼 보입니다. –

+0

오. 예. 죄송합니다. 나는 그것을 새롭게 할 것이다. –