MVC 3 多角色多用户动态授权

发布于 2024-11-16 13:07:28 字数 749 浏览 2 评论 0原文

我最近开始进行 MVC 3 开发,但从早些时候开始就有 C# 和 ASP.NET 方面的经验。所以我将从我想要完成的事情开始。我开发了一个用于托管文章的小网站。我已经在该网站上实施了基于 SQLServer 的会员管理。现在我想创建一个凭据系统来限制并允许正确的用户创建、删除和更新文章。有一个简单的解决方案,那就是这样做:

[Authorize(Roles="Admin")]
    public ActionResult UpdateArticle(ArticleModel model, int articleid)
    {
        return View();
    }

现在这真的很简单。我只是说,只有“管理员”角色的成员才被允许更新文章。但这只是静态的。因此,我在数据库中创建了一个凭据表,该表最后告诉我“第 5 条可以由角色 1、2、3 和 4 以及用户 A、b 和 C 编辑”。到目前为止,一切都很好。但我如何使用授权解决方案来实现这一点呢?

我想做这样的事情:

[Authorize(getAuthorizedusers("update",this.articleid))]

getAuthorizedusers 返回哪些用户和角色被授权使用传递给它的articleid 来更新文章。

所以我这里(至少)有两个问题: -获取授权方法来接受多个用户和角色。 - 将发送到 UpdateArticle 方法的提供的articleid 传递到getAuthorizedusers 方法。

I recently starded developing for MVC 3 but have experience in both C# and ASP.NET since earlier. So i'll start with what i'm trying to accomplish. I've developed a small site for hosting articles. I've implemented SQLServer based membership managament to the site. Now i want to create a credentials system that restricts and allows the right users to create, delete and update articles. There is one simple solution to this and that is to do it like this:

[Authorize(Roles="Admin")]
    public ActionResult UpdateArticle(ArticleModel model, int articleid)
    {
        return View();
    }

Now this is really simple. I simply say that only members that are in the role "Admin" are allowed to update an article. But that's just to static. So i created a credentials table in my database that in the end tells me that "Article 5 can be edited by roles 1,2,3 & 4 and by users A, b & C". So far so good. But how would i implement that with the Authorize solution?

I would like to do something like this:

[Authorize(getAuthorizedusers("update",this.articleid))]

where getAuthorizedusers returns which users and roles are authorized to update the article with the articleid that was passed to it.

So I have (at least) two problems here:
-Getting the Authorize method to accept multiple users and roles.
-Passing the supplied articleid, that was sent to the UpdateArticle method, to the getAuthorizedusers method.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

几度春秋 2024-11-23 13:07:29

这是完成同样事情的更简单的方法:

[Authorize]
public ActionResult UpdateArticle(ArticleModel model, int articleid)
{
    // if current user is an article editor
    return View();
    // else
    return View("Error");
}

Here's a much easier way to accomplish the same thing:

[Authorize]
public ActionResult UpdateArticle(ArticleModel model, int articleid)
{
    // if current user is an article editor
    return View();
    // else
    return View("Error");
}
夏雨凉 2024-11-23 13:07:29

当我重写 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;
    }

I got it working as I wanted when I overrode the AuthorizeCore method and authorizes the way I want to.

    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;
    }
不乱于心 2024-11-23 13:07:28

您可以创建自己的自定义属性,该属性继承自 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
    }
}

用法如下所示:

[ArticleAuthorize(Action=ArticleAuthorizeAttribute.ArticleAction.Update)]

编辑:进一步研究后,您似乎无法将 this.articleID 传递到属性中。但是,您确实可以通过 QueryString 属性或 Form 属性访问 filterContext.HttpContext.Request 中的参数,具体取决于您的方式传递值。我已经适当更新了代码示例。

可以在此处找到更完整的示例,

使用以下命令检查授权用户角色和用户列表,您可以执行如下操作:

        var allowedUsers = new List<string>();
        //populate allowedUsers from DB

        If (User.IsInRole("Update") || allowedUsers.Contains(User.Identity.Name))
        {
            //authorized
        }

或者,您可以直接在一个方法中对数据库进行两项检查,以避免进行两次调用。

You can create your own custom attribute that inherits from AuthorizeAttribute and override the OnAuthorize method to do what you need.

This should get you started:

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
    }
}

The usage would look like this:

[ArticleAuthorize(Action=ArticleAuthorizeAttribute.ArticleAction.Update)]

Edit: After looking into this a bit more, it looks like you can't pass this.articleID in to the attribute. However, you do have access to the parameters from filterContext.HttpContext.Request through the QueryString property or the Form property, depending on how you are passing the values. I have updated the code sample appropriately.

A more complete example can be found here

To check for authorization using user role and user list you would do something like this:

        var allowedUsers = new List<string>();
        //populate allowedUsers from DB

        If (User.IsInRole("Update") || allowedUsers.Contains(User.Identity.Name))
        {
            //authorized
        }

Alternatively, you can do both checks against the DB directly in a single method to keep from making two calls.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文