2012-08-07 7 views
3

폼 인증을 사용하여 Active Directory에 대해 인증하는 MVC 응용 프로그램이 있습니다. 내 MVC 응용 프로그램의 크기가 가운이므로, 내가하고있는 역할 검사가 점점 더 단편화되고 있음이 분명해졌습니다.Active Directory 역할을 기반으로 한 사용 권한

[AuthorizePermission(Permission.CanDoSomething)]Thead.CurrentPrincipal.HasPermission(Permission.CanDoSomething)

곳 권한이 열거입니다 :의 라인을 따라 뭔가

[Authorize(Roles = "Staff")]Thread.CurrentPrincipal.IsInRole("Staff")

: 내가 좋아하는 일을 대체합니다. 지금은 내가 지금처럼 Web.config의 각 AD 역할이 갖고있는 권한을 정의 할 수 있다고 생각했다 : 나는 다음 IPrincipal 확장 방법을 구현할 수

<role name="Staff"> 
    <permissions> 
     <add name="CreateEditDeleteSomething" /> 
     <add name="PublishSomething" /> 
     <add name="QueryUsers" /> 
    </permissions> 
    </role> 

- HasPermission(Permission permission)합니다. 이렇게하면 사용자가 web.config에 정의 된대로 권한이 전달 된 AD 그룹 중 누구에게 알리는 지 알 수 있습니다. 이렇게하면 특정 AD goup가 코드를 변경하거나 기존 테스트를 업데이트하지 않고도 사용 권한을 변경할 수 있습니다. 그런 다음 사용자 지정 권한 부여 특성은 HasPermission 메서드를 호출 할 수 있습니다.

이 방법이 맞습니까? 아니면 응용 프로그램 내에서 역할을 단순화하는 더 나은 방법이 있습니까? 나는 여기와 웹에서 여러 가지 예를 보았지만 지나치게 복잡해 보였다. HasPermission의 web.config 역할 설정에 대한 Permission이 전달되었는지 확인하면됩니다. IPrincipal은 AD 역할을 가지므로 확실하게 허용 된 사용 권한을 결정하는 것이 쉽습니다.

도움을 주셨습니다.

답변

1

권한은 역할보다 훨씬 복잡합니다.

나는이 문제가있다 해결할 방법을 "삭제"종종 CreateEditDelete 등의 권한 그룹이있을 수 있습니다 ...하지만 또한 단지, ​​"편집" "만들기"와 같은 세분화 된 하위 집합 자신 할 수있다 사용자가 비즈니스 규칙 컨텍스트와 해당 AD 역할을 부여해야하는 권한을 판별 할 수있는 PermissionsManger 클래스를 작성하십시오.

비트 단위 플래그를 사용하여 세분화 된 사용 권한의 복잡성을 단순화했습니다.

역할을 사용 권한에 매핑하는 방법은 전적으로 귀하에게 달려 있습니다.

using System; 
using System.Linq; 
using System.Security.Principal; 

// Install-Package FluentAssertions -Pre 
using FluentAssertions; 

public static class ExtensionsForIPrincipal 
{ 
    public static bool HasPermission(this IPrincipal principal, Permissions permission) 
    { 
     return PermissionsManager.GetUserPermissions(principal).HasFlag(permission); 
    } 

    public static bool IsInRole(this IPrincipal principal, params string[] roleNames) 
    { 
     return roleNames.Any(principal.IsInRole); 
    } 
} 

public static class PermissionsManager 
{ 
    public static Permissions GetUserPermissions(IPrincipal user) 
    { 
     if (user.IsInRole("admin")) 
     { 
      return Permissions.All; 
     } 

     var userPermissions = Permissions.None; 

     if (user.IsInRole("staff", "user")) 
     { 
      userPermissions |= Permissions.QueryUsers; 
     } 

     if (user.IsInRole("staff")) 
     { 
      userPermissions |= Permissions.PermissionsCreateEditDeleteSomething | Permissions.QueryUsers; 
     } 

     if (user.IsInRole("editor")) 
     { 
      userPermissions |= Permissions.PublishSomething; 
     } 

     return userPermissions; 
    } 
} 

[Flags] 
public enum Permissions 
{ 
    None = 0, 
    CreateSomething = 1, 
    EditSomething = 2, 
    DeleteSomething = 4, 
    PublishSomething = 8, 
    QueryUsers = 16, 
    PermissionsCreateEditDeleteSomething = CreateSomething | EditSomething | DeleteSomething, 
    All = PermissionsCreateEditDeleteSomething | PublishSomething | QueryUsers 
} 

internal class Program 
{ 
    private static void Main(string[] args) 
    { 
     IPrincipal admin = Create("james", "admin"); 

     PermissionsManager.GetUserPermissions(admin).ShouldBeEquivalentTo(Permissions.All); 

     admin.HasPermission(Permissions.None).Should().BeTrue(); 
     admin.HasPermission(Permissions.EditSomething).Should().BeTrue(); 
     admin.HasPermission(Permissions.PermissionsCreateEditDeleteSomething).Should().BeTrue(); 
     admin.HasPermission(Permissions.PublishSomething).Should().BeTrue(); 
     admin.HasPermission(Permissions.QueryUsers).Should().BeTrue(); 
     admin.HasPermission(Permissions.All).Should().BeTrue(); 

     IPrincipal editor = Create("susan", "editor", "staff"); 

     editor.HasPermission(Permissions.None).Should().BeTrue(); 
     editor.HasPermission(Permissions.EditSomething).Should().BeTrue(); 
     editor.HasPermission(Permissions.PermissionsCreateEditDeleteSomething).Should().BeTrue(); 
     editor.HasPermission(Permissions.QueryUsers).Should().BeTrue(); 
     editor.HasPermission(Permissions.PublishSomething).Should().BeTrue(); 
     editor.HasPermission(Permissions.All).Should().BeTrue(); 

     IPrincipal staff = Create("michael", "staff"); 

     staff.HasPermission(Permissions.None).Should().BeTrue(); 
     staff.HasPermission(Permissions.EditSomething | Permissions.DeleteSomething).Should().BeTrue(); 
     staff.HasPermission(Permissions.PermissionsCreateEditDeleteSomething).Should().BeTrue(); 
     staff.HasPermission(Permissions.QueryUsers).Should().BeTrue(); 
     staff.HasPermission(Permissions.PublishSomething).Should().BeFalse(); 
     staff.HasPermission(Permissions.All).Should().BeFalse(); 

     IPrincipal user = Create("bob", "user"); 

     user.HasPermission(Permissions.None).Should().BeTrue(); 
     user.HasPermission(Permissions.EditSomething).Should().BeFalse(); 
     user.HasPermission(Permissions.PermissionsCreateEditDeleteSomething).Should().BeFalse(); 
     user.HasPermission(Permissions.QueryUsers).Should().BeTrue(); 
     user.HasPermission(Permissions.PublishSomething).Should().BeFalse(); 
     user.HasPermission(Permissions.All).Should().BeFalse(); 

     IPrincipal anon = Create("anonymous"); 

     anon.HasPermission(Permissions.None).Should().BeTrue(); 
     anon.HasPermission(Permissions.EditSomething).Should().BeFalse(); 
     anon.HasPermission(Permissions.PermissionsCreateEditDeleteSomething).Should().BeFalse(); 
     anon.HasPermission(Permissions.QueryUsers).Should().BeFalse(); 
     anon.HasPermission(Permissions.PublishSomething).Should().BeFalse(); 
     anon.HasPermission(Permissions.All).Should().BeFalse(); 

     Console.WriteLine("All tests passed"); 
     Console.ReadLine(); 
    } 

    private static IPrincipal Create(string name, params string[] roles) 
    { 
     return new GenericPrincipal(new GenericIdentity(name), roles); 
    } 
}