asp.net mvc 장식[권한()] 여러 enums 함께




asp net identity claims (6)

컨트롤러가있어서 두 가지 역할을 통해 액세스 할 수 있어야합니다. 1-admin 또는 2-moderator

[권한 부여 (역할 = "관리자, 중재자")] 할 수 있음을 알고 있지만 열거 형에서 내 역할을 수행합니다. 열거 형에서는 하나의 역할 만 권한을 부여 할 수 있습니다. 나는 두 권을 인증하는 방법을 알 수 없다.

나는 [Authorize (Roles = MyEnum.Admin, MyEnum.Moderator)]와 같은 것을 시도했지만 컴파일이 안된다.

누군가 한 번이 제안 :

 [Authorize(Roles=MyEnum.Admin)]
 [Authorize(MyEnum.Moderator)]
 public ActionResult myAction()
 {
 }

하지만 OR로 작동하지는 않습니다. 나는이 경우 사용자가 두 역할의 일부가되어야한다고 생각한다. 나는 어떤 구문을 간과하고 있는가? 아니면 내 자신의 권한을 굴려야하는 경우입니까?


또는 다음과 같이 연결할 수 있습니다.

[권한 부여 (역할 = Common.Lookup.Item.SecurityRole.Administrator + ","+ Common.Lookup.Item.SecurityRole.Intake)]


CalebHC의 코드에 추가하고 여러 역할을 가진 사용자를 처리하는 ssmith의 질문에 대답하려면 ...

사용자 지정 보안 주체는 사용자가 속한 모든 그룹 / 역할을 나타내는 문자열 배열을 반환합니다. 먼저 열의 항목과 일치하는 배열의 모든 문자열을 변환해야합니다. 마지막으로 일치하는 항목을 찾습니다. 일치하는 경우 사용자에게 권한이 부여됩니다.

권한이없는 사용자를 사용자 지정 "NotAuthorized"보기로 리디렉션합니다.

전체 클래스는 다음과 같습니다.

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)] 
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
    /// <summary>
    /// Add the allowed roles to this property.
    /// </summary>
    public Roles Is { get; set; }

    /// <summary>
    /// Checks to see if the user is authenticated and has the
    /// correct role to access a particular view.
    /// </summary>
    /// <param name="httpContext"></param>
    /// <returns></returns>
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        if (httpContext == null)
            throw new ArgumentNullException("httpContext");

        if (!httpContext.User.Identity.IsAuthenticated)
            return false;

        var iCustomPrincipal = (ICustomPrincipal) httpContext.User;

        var roles = iCustomPrincipal.CustomIdentity
                        .GetGroups()
                        .Select(s => Enum.Parse(typeof (Roles), s))
                        .ToArray();

        if (Is != 0 && !roles.Cast<Roles>().Any(role => ((Is & role) == role)))
        {
            return false;
        }

        return true;
    }

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        if (filterContext == null)
            throw new ArgumentNullException("filterContext");

        filterContext.Result = new ViewResult { ViewName = "NotAuthorized" };
    } 
}

나는 개인적인 마음에 드는 것을 창조하기 위하여 여기에서 해결책의 약간을 결합했다. 내 사용자 지정 특성은 SimpleMembership에서 예상하는 형식으로 데이터를 변경하고 다른 모든 작업을 처리 할 수있게합니다.

내 역할 열거 형 :

public enum MyRoles
{
    Admin,
    User,
}

역할을 만들려면 다음을 수행하십시오.

public static void CreateDefaultRoles()
{
    foreach (var role in Enum.GetNames(typeof(MyRoles)))
    {
       if (!Roles.RoleExists(role))
       {
            Roles.CreateRole(role);
        }
    }
}

맞춤 속성 :

public class AuthorizeRolesAttribute : AuthorizeAttribute
{
    public AuthorizeRolesAttribute(params MyRoles[] allowedRoles)
    {
        var allowedRolesAsStrings = allowedRoles.Select(x => Enum.GetName(typeof(MyRoles), x));
        Roles = string.Join(",", allowedRolesAsStrings);
    }
}

그렇게 사용 :

[AuthorizeRoles(MyRoles.Admin, MyRoles.User)]
public ActionResult MyAction()
{
    return View();
}

다음 구문을 사용하면 간단 하고 우아한 솔루션을 얻을 수 있습니다.

[AuthorizeRoles(MyEnum.Admin, MyEnum.Moderator)]

자신의 속성을 만들 때 생성자에서 params 키워드를 사용하십시오.

public class AuthorizeRoles : AuthorizeAttribute
{
    public AuthorizeRoles(params MyEnum[] roles)
    {
        ...
    }
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        ...
    }
}

이렇게하면 다음과 같이 속성을 사용할 수 있습니다.

[AuthorizeRoles(MyEnum.Admin, MyEnum.Moderator)]
public ActionResult myAction()
{
}

시험

public class CustomAuthorize : AuthorizeAttribute
{
    public enum Role
    {
        DomainName_My_Group_Name,
        DomainName_My_Other_Group_Name
    }

    public CustomAuthorize(params Role[] DomainRoles)
    {
        foreach (var domainRole in DomainRoles)
        {
            var domain = domainRole.ToString().Split('_')[0] + "_";
            var role = domainRole.ToString().Replace(domain, "").Replace("_", " ");
            domain=domain.Replace("_", "\\");
            Roles += ", " + domain + role;
        }
        Roles = Roles.Substring(2);
    }       
}

public class HomeController : Controller
{
    [CustomAuthorize(Role.DomainName_My_Group_Name, Role.DomainName_My_Other_Group_Name)]
    public ActionResult Index()
    {
        return View();
    }
}

다음과 같이 비트 OR 연산자를 사용해보십시오.

[Authorize(Roles= MyEnum.Admin | MyEnum.Moderator)]
public ActionResult myAction()
{
}

그것이 작동하지 않으면, 당신은 자신의 롤 수 있습니다. 나는 현재 내 프로젝트에서이 작업을 수행했다. 여기 내가 한 일이있다.

public class AuthWhereRole : AuthorizeAttribute
{
    /// <summary>
    /// Add the allowed roles to this property.
    /// </summary>
    public UserRole Is;

    /// <summary>
    /// Checks to see if the user is authenticated and has the
    /// correct role to access a particular view.
    /// </summary>
    /// <param name="httpContext"></param>
    /// <returns></returns>
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        if (httpContext == null)
            throw new ArgumentNullException("httpContext");

        // Make sure the user is authenticated.
        if (!httpContext.User.Identity.IsAuthenticated)
            return false;

        UserRole role = someUser.Role; // Load the user's role here

        // Perform a bitwise operation to see if the user's role
        // is in the passed in role values.
        if (Is != 0 && ((Is & role) != role))
            return false;

        return true;
    }
}

// Example Use
[AuthWhereRole(Is=MyEnum.Admin|MyEnum.Newbie)]
public ActionResult Test() {}

또한 열거 형에 flags 속성을 추가하고 값이 모두 1 이상이어야합니다. 이렇게 :

[Flags]
public enum Roles
{
    Admin = 1,
    Moderator = 1 << 1,
    Newbie = 1 << 2
    etc...
}

왼쪽 비트 시프 팅은 값 1, 2, 4, 8, 16 등을 제공합니다.

글쎄, 나는 이것이 조금 도움이되기를 바랍니다.







roles