ASP.NET MVC 4 Thuộc tính ủy quyền tùy chỉnh với mã cho phép (không có vai trò)


121

Tôi cần kiểm soát quyền truy cập vào các chế độ xem dựa trên các cấp đặc quyền của người dùng (không có vai trò, chỉ có các cấp đặc quyền cho các cấp hoạt động CRUD được chỉ định cho người dùng) trong ứng dụng MVC 4 của mình.

Như một ví dụ; bên dưới AuthorizeUser sẽ là thuộc tính tùy chỉnh của tôi và tôi cần sử dụng nó như sau:

[AuthorizeUser(AccessLevels="Read Invoice, Update Invoice")]
public ActionResult UpdateInvoice(int invoiceId)
{
   // some code...
   return View();
}


[AuthorizeUser(AccessLevels="Create Invoice")]
public ActionResult CreateNewInvoice()
{
  // some code...
  return View();
}


[AuthorizeUser(AccessLevels="Delete Invoice")]
public ActionResult DeleteInvoice(int invoiceId)
{
  // some code...
  return View();
}

Có thể làm theo cách này không?

Câu trả lời:


243

Tôi có thể làm điều này với một thuộc tính tùy chỉnh như sau.

[AuthorizeUser(AccessLevel = "Create")]
public ActionResult CreateNewInvoice()
{
    //...
    return View();
}

Lớp Thuộc tính tùy chỉnh như sau.

public class AuthorizeUserAttribute : AuthorizeAttribute
{
    // Custom property
    public string AccessLevel { get; set; }

    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        var isAuthorized = base.AuthorizeCore(httpContext);
        if (!isAuthorized)
        {                
            return false;
        }

        string privilegeLevels = string.Join("", GetUserRights(httpContext.User.Identity.Name.ToString())); // Call another method to get rights of the user from DB

        return privilegeLevels.Contains(this.AccessLevel);           
    }
}

Bạn có thể chuyển hướng người dùng trái phép theo tùy chỉnh của mình AuthorisationAttributebằng cách ghi đè HandleUnauthorizedRequestphương thức:

protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
    filterContext.Result = new RedirectToRouteResult(
                new RouteValueDictionary(
                    new
                        { 
                            controller = "Error", 
                            action = "Unauthorised" 
                        })
                );
}

Tôi đã thử ví dụ của bạn về HandleUnauthorizedRequest nhưng khi tôi chỉ định RouteValueDictionary, nó chỉ chuyển hướng đến tôi một tuyến đường không tồn tại. Nó gắn thêm con đường tôi muốn chuyển hướng người dùng đến các tuyến đường mà người dùng muốn truy cập ... si tôi nhận được một cái gì đó như: localhost: 9999 / admin / Home khi tôi muốn localhost: 9999 / Trang chủ
Marin

1
@Marin Cố gắng thêm area = string.Empty vào RouteValueDictionary
Alex

30
Tôi đã ủng hộ nhưng sau đó tôi thấy "if (condition) {return true;} else {return false;}" ở cuối ....
GabrielBB

1
@Emil Tôi chỉ đơn giản trả về boolean mà phương thức String.Contains đã cung cấp cho tôi. Nhưng điều này không liên quan, tôi đã không phản đối, tôi chỉ không ủng hộ thôi hehe.
GabrielBB

2
.Name.ToString()là không cần thiết, vì Nametài sản đã là chuỗi
FindOutIslamNow

13

Đây là một sửa đổi cho hiện tại. câu trả lời. Sự khác biệt chính là khi người dùng không được xác thực, nó sử dụng phương thức "HandleUnauthorizedRequest" ban đầu để chuyển hướng đến trang đăng nhập:

   protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {

        if (filterContext.HttpContext.User.Identity.IsAuthenticated) {

            filterContext.Result = new RedirectToRouteResult(
                        new RouteValueDictionary(
                            new
                            {
                                controller = "Account",
                                action = "Unauthorised"
                            })
                        );
        }
        else
        {
             base.HandleUnauthorizedRequest(filterContext);
        }
    }

3

Có thể điều này hữu ích cho bất kỳ ai trong tương lai, tôi đã triển khai Thuộc tính ủy quyền tùy chỉnh như thế này:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class ClaimAuthorizeAttribute : AuthorizeAttribute, IAuthorizationFilter
{
    private readonly string _claim;

    public ClaimAuthorizeAttribute(string Claim)
    {
        _claim = Claim;
    }

    public void OnAuthorization(AuthorizationFilterContext context)
    {
        var user = context.HttpContext.User;
        if(user.Identity.IsAuthenticated && user.HasClaim(ClaimTypes.Name, _claim))
        {
            return;
        }

        context.Result = new ForbidResult();
    }
}

0

Nếu bạn sử dụng API WEB với Xác nhận quyền sở hữu, bạn có thể sử dụng điều này:

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
public class AutorizeCompanyAttribute:  AuthorizationFilterAttribute
{
    public string Company { get; set; }

    public override void OnAuthorization(HttpActionContext actionContext)
    {
        var claims = ((ClaimsIdentity)Thread.CurrentPrincipal.Identity);
        var claim = claims.Claims.Where(x => x.Type == "Company").FirstOrDefault();

        string privilegeLevels = string.Join("", claim.Value);        

        if (privilegeLevels.Contains(this.Company)==false)
        {
            actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized, "Usuario de Empresa No Autorizado");
        }
    }
}
[HttpGet]
[AutorizeCompany(Company = "MyCompany")]
[Authorize(Roles ="SuperAdmin")]
public IEnumerable MyAction()
{....
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.