C# MVC 3多角色和用户的动态授权
我最近开始为MVC 3开发,但从早些时候开始,我在C#和ASP.NET方面都有经验。因此,我将从我试图实现的目标开始。我已经开发了一个小网站来托管文章。我已经对站点实施了基于SQLServer的成员管理。现在我想创建一个凭证系统,它限制并允许正确的用户创建、删除和更新文章。有一个简单的解决方案,就是这样做:C# MVC 3多角色和用户的动态授权,c#,asp.net,asp.net-mvc-3,authorization,C#,Asp.net,Asp.net Mvc 3,Authorization,我最近开始为MVC 3开发,但从早些时候开始,我在C#和ASP.NET方面都有经验。因此,我将从我试图实现的目标开始。我已经开发了一个小网站来托管文章。我已经对站点实施了基于SQLServer的成员管理。现在我想创建一个凭证系统,它限制并允许正确的用户创建、删除和更新文章。有一个简单的解决方案,就是这样做: [Authorize(Roles="Admin")] public ActionResult UpdateArticle(ArticleModel model, int articl
[Authorize(Roles="Admin")]
public ActionResult UpdateArticle(ArticleModel model, int articleid)
{
return View();
}
[Authorize(getAuthorizedusers("update",this.articleid))]
[ArticleAuthorize(Action=ArticleAuthorizeAttribute.ArticleAction.Update)]
var allowedUsers = new List<string>();
//populate allowedUsers from DB
If (User.IsInRole("Update") || allowedUsers.Contains(User.Identity.Name))
{
//authorized
}
这真的很简单。我只是说,只有扮演“管理员”角色的成员才能更新文章。但这只是静态的。因此,我在数据库中创建了一个凭证表,最后它告诉我“第5条可以由角色1、2、3和4以及用户a、b和C编辑”。到现在为止,一直都还不错。但我如何使用授权解决方案实现这一点
我想这样做:
[Authorize(Roles="Admin")]
public ActionResult UpdateArticle(ArticleModel model, int articleid)
{
return View();
}
[Authorize(getAuthorizedusers("update",this.articleid))]
[ArticleAuthorize(Action=ArticleAuthorizeAttribute.ArticleAction.Update)]
var allowedUsers = new List<string>();
//populate allowedUsers from DB
If (User.IsInRole("Update") || allowedUsers.Contains(User.Identity.Name))
{
//authorized
}
其中getAuthorizedusers返回哪些用户和角色有权使用传递给它的articleid更新文章
所以我这里(至少)有两个问题:
-正在获取授权方法以接受多个用户和角色。
-将提供的articleid(发送到UpdateArticle方法)传递到getAuthorizedusers方法。这里有一个更简单的方法来完成同样的任务:
[Authorize]
public ActionResult UpdateArticle(ArticleModel model, int articleid)
{
// if current user is an article editor
return View();
// else
return View("Error");
}
您可以创建自己的自定义属性,该属性继承自
AuthorizeAttribute
,并重写OnAuthorize
方法以执行所需操作
这应该让你开始:
public class ArticleAuthorizeAttribute : AuthorizeAttribute
{
public enum ArticleAction
{
Read,
Create,
Update,
Delete
}
public ArticleAction Action { get; set; }
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
//do custom authorizization using Action and getting ArticleID
//from filterContext.HttpContext.Request.QueryString or
//filterContext.HttpContext.Request.Form
}
}
用法如下所示:
[Authorize(Roles="Admin")]
public ActionResult UpdateArticle(ArticleModel model, int articleid)
{
return View();
}
[Authorize(getAuthorizedusers("update",this.articleid))]
[ArticleAuthorize(Action=ArticleAuthorizeAttribute.ArticleAction.Update)]
var allowedUsers = new List<string>();
//populate allowedUsers from DB
If (User.IsInRole("Update") || allowedUsers.Contains(User.Identity.Name))
{
//authorized
}
编辑:进一步研究后,您似乎无法将this.articleID传递给属性。但是,您确实可以通过QueryString
属性或Form
属性从filterContext.HttpContext.Request
访问参数,具体取决于传递值的方式。我已经适当地更新了代码示例
可以找到一个更完整的例子
要使用用户角色和用户列表检查授权,请执行以下操作:
[Authorize(Roles="Admin")]
public ActionResult UpdateArticle(ArticleModel model, int articleid)
{
return View();
}
[Authorize(getAuthorizedusers("update",this.articleid))]
[ArticleAuthorize(Action=ArticleAuthorizeAttribute.ArticleAction.Update)]
var allowedUsers = new List<string>();
//populate allowedUsers from DB
If (User.IsInRole("Update") || allowedUsers.Contains(User.Identity.Name))
{
//authorized
}
var allowedUsers=new List();
//从数据库填充allowedUsers
If(User.IsInRole(“更新”)| | allowedUsers.Contains(User.Identity.Name))
{
//授权
}
或者,您可以在一个方法中直接对DB执行这两项检查,以避免进行两次调用。当我覆盖AuthorizeCore方法并以我想要的方式进行授权时,我让它按我想要的方式工作
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (httpContext == null)
{
throw new ArgumentNullException("httpContext");
}
IPrincipal user = httpContext.User;
if (!user.Identity.IsAuthenticated)
{
return false;
}
if ((_usersSplit.Length > 0 && !_usersSplit.Contains(user.Identity.Name, StringComparer.OrdinalIgnoreCase)) && (_rolesSplit.Length > 0 && !_rolesSplit.Any(user.IsInRole)))
{
return false;
}
return true;
}
谢谢,非常有帮助!我会努力实现这个,然后带着结果回来!你好!现在我已经尝试了,并且取得了部分成功。使用用户和角色进行授权时,仅授权具有指定角色的指定用户。我希望它是指定的用户,或者具有指定角色的用户。这有可能以某种方式修复吗?@Anton,您需要直接查询数据库以获得显式访问。由于您必须直接访问数据库以获取其中的一部分,因此您可能需要编写一个方法,该方法接受用户名、角色和articleID,并返回它们是否具有访问权限
UserCanPerformAction(User.Identity.Name,“Update”,23)
我想你不明白我的问题是什么,可能是因为我描述得不好=)。在OnAuthorizatoin方法中,如果我写:`Users=“Anton”`user“Anton”将是唯一有权做某事的人。如果我只写:'Roles=“Admin”'只有组“Admin”中的用户才能执行某些操作。但是如果我写:'Users=“Anton Roles=“Admin”'用户“Anton”只有在拥有“Admin”权限时才会被授权“角色。但我希望用户Anton获得授权,所有具有“管理员”角色的人都获得授权。@Anton,我想这就是你的意思:)我已经更新了我的答案,包括一个简短的片段,用于检查用户列表或角色成员身份以获得授权。您需要编写特定于您的情况的DB代码(ADO.net、实体框架、Linq到SQL等)