C# 如何为角色以及特定用户使用自定义授权属性?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11493873/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use custom Authorize attribute for roles as well as a specific user?
提问by Freeman
so 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 wich 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 recieveing the PostEntry id as a route parameter but thats after the atribute and also attributes only accept constant parameters, looks like something very difficult, your answers are highly appreciated, Cheers!
在我的情况下,我需要授权管理员以便他们可以编辑帖子,但是(这里是很酷的部分),我还需要允许帖子的创建者能够编辑帖子,即普通用户。那么我怎样才能过滤掉创建帖子的用户和管理员,但让其他人未经授权呢?我收到 PostEntry id 作为路由参数,但那是在属性之后,而且属性也只接受常量参数,看起来非常困难,非常感谢您的回答,干杯!
采纳答案by Darin Dimitrov
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();
}
回答by Traderhut Games
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:
这具有以下优点:
- No additional class that someone will later wonder where it is used.
- No class that isn't usable anywhere else (you don't gain reuse with a custom attribute)
- Performance is better: Single fetch of the Post
- Way easier for someone to read/figure out how it works. No magic code to track down.
- 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...
- 没有其他人以后会想知道它在哪里使用的附加类。
- 没有在其他任何地方都无法使用的类(您不会通过自定义属性获得重用)
- 性能更好:Post 的单次获取
- 有人更容易阅读/弄清楚它是如何工作的。没有神奇的代码可以追踪。
- 多年后,当 HttpContextBase 类不存在,或者用于获取 Id 参数的其他部分技巧消失时,代码仍然有效......

