简体   繁体   English

如何为角色以及特定用户使用自定义授权属性?

[英]How to use custom Authorize attribute for roles as well as a specific user?

I have my Action Method我有我的行动方法

[Authorize(Roles="Admin")]
public ActionResult EditPosts(int id)
{
    return View();
}

In my case I need to authorize administrators so they can edit posts but (here comes the cool part), I also need to allow the creator of the post to be able to edit the post which is a normal user.在我的情况下,我需要授权管理员以便他们可以编辑帖子,但是(这里是很酷的部分),我还需要允许帖子的创建者能够编辑普通用户的帖子。 So how can I filter out the user that created the post as well as the admins but leave the others unauthorized?那么如何过滤掉创建帖子的用户和管理员,但让其他人未经授权呢? I am receiving the PostEntry id as a route parameter but that's after the attribute and also attributes only accept constant parameters, looks like something very difficult, your answers are highly appreciated, Cheers!我收到 PostEntry id 作为路由参数,但这是在属性之后,而且属性只接受常量参数,看起来非常困难,非常感谢您的回答,干杯!

You could write a custom authorize attribute:您可以编写自定义授权属性:

public class AuthorizeAdminOrOwnerOfPostAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        var authorized = base.AuthorizeCore(httpContext);
        if (!authorized)
        {
            // The user is not authenticated
            return false;
        }

        var user = httpContext.User;
        if (user.IsInRole("Admin"))
        {
            // Administrator => let him in
            return true;
        }

        var rd = httpContext.Request.RequestContext.RouteData;
        var id = rd.Values["id"] as string;
        if (string.IsNullOrEmpty(id))
        {
            // No id was specified => we do not allow access
            return false;
        }

        return IsOwnerOfPost(user.Identity.Name, id);
    }

    private bool IsOwnerOfPost(string username, string postId)
    {
        // TODO: you know what to do here
        throw new NotImplementedException();
    }
}

and then decorate your controller action with it:然后用它装饰你的控制器动作:

[AuthorizeAdminOrOwnerOfPost]
public ActionResult EditPosts(int id)
{
    return View();
}

I understand that you have already accepted an answer, and this was posted a while back.. (btw:excellent answer for adding custom attributes), However I would point out the following:我知道您已经接受了一个答案,并且这是在不久前发布的..(顺便说一句:添加自定义属性的优秀答案),但是我要指出以下几点:

If you are using this attribute once.如果您使用此属性一次。 On a Single method.在单一方法上。 This isn't a good implementation.这不是一个好的实现。 Instead you should have:相反,你应该有:

[Authorize]   // Just make sure they are auth'ed at all.
public ActionResult EditPosts(int id)
{
    Post SomePost = findPostByID (id);   // However you do it - single lookup of post

    if (!user.IsInRole("Admin") &&  !{IsOwnerOfPost(post)} )  Return Not Authorized

  ... Edit post code here
}

This has the advantages of:这具有以下优点:

  1. No additional class that someone will later wonder where it is used.没有其他人以后会想知道它在哪里使用的附加类。
  2. No class that isn't usable anywhere else (you don't gain reuse with a custom attribute)没有在其他任何地方都无法使用的类(您不会通过自定义属性获得重用)
  3. Performance is better: Single fetch of the Post性能更好:Post 的单次获取
  4. Way easier for someone to read/figure out how it works.人们更容易阅读/弄清楚它是如何工作的。 No magic code to track down.没有神奇的代码可以追踪。
  5. And Years later, when HttpContextBase class doesn't exist, or other parts of the tricks used to fetch the Id parameter are gone, the code still works...多年后,当 HttpContextBase 类不存在,或者用于获取 Id 参数的其他部分技巧消失时,代码仍然有效......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM