ASP.NET MVC使用角色进行授权

24

我正在创建一个asp.net mvc应用程序,其中包含用户概念。每个用户都能够编辑自己的个人资料。例如:

没有什么特别的......

然而,我在授权方案上遇到了一些麻烦。系统中目前只有两个角色:“管理员”和“默认用户”,但未来可能会有更多角色。

我无法使用常规的Authorize属性来指定授权,因为这两个用户都属于相同的角色(即“默认用户”)。

因此,如果我像下面这样指定Authorize过滤器:

[Authorize(Roles = "DefaultUser")]

那么就没有影响。PersonID=1可以进入并编辑自己的个人资料(正如他们应该能够),但他们也可以更改URL为http://localhost/person/edit/2,然后完全访问和编辑PersonID=2的资料(这是不应该允许的)。

这是否意味着我必须创建自己的授权过滤器,在允许用户访问之前检查用户请求的操作是否“属于”他们?也就是说,如果当前登录的用户请求参数为1的编辑操作,我需要进行自定义检查以确保当前登录的人是PersonID=1,如果是,则授权给他们,如果不是,则拒绝访问吗?

感觉好像我漏了什么显而易见的东西,所以任何指导将不胜感激。


@Wojtek 这里有人谈论nerddinnerbook:https://dev59.com/questions/9nM_5IYBdhLWcg3waieJ - user969533
我认为这里的解决方案可能会对你有所帮助:https://dev59.com/qmgu5IYBdhLWcg3wMkfF - Jackson S
5个回答

62

也许你可以组织控制器操作,使得URL更像http://localhost/person/editme,并显示当前登录用户的编辑表单。这样,用户就无法通过篡改URL来编辑其他人的信息。


1
这是我使用的解决方案,到目前为止它运行得非常好。 - BoxOfNotGoodery

36

我的观点:

授权和认证是两个不同的概念。简而言之,问题是你能做这件事吗,你应该做吗?你可以选择你的朋友,你可以挖你的鼻子,但你不能挑选你的朋友的鼻子!如果每个角色都可以执行它(用户有手和鼻子),那么就没有必要检查授权。为用户设置一个发布方法来获取他们自己的个人资料,并使用表单的隐藏值或重定向测试个人资料ID(不要碰我的鼻子,走开)。

为编辑他人个人资料设置一个获取方法,并在此处仅检查管理员角色 - (我是医生,我有权将东西塞进你的鼻子中)...


16
更优雅的解决方案是编写自己的授权操作过滤器,可以通过扩展[Authorize]或实现IAuthorizationFilter来实现,如下所示:
public class AuthorizeOwnerAttribute: FilterAttribute, IAuthorizationFilter
{
    #region IAuthorizationFilter Members

    public void OnAuthorization(AuthorizationContext filterContext)
    {
        // add logic here that compares the currently logged in user, to the owner of the profile that is being edited
        // get currently logged in user info from filterContext.HttpContext.User.Identity;
        // get profile being edited from filterContext.RouteData or filterContext.Something
    }

    #endregion
}

我不确定OnAuthorization方法实际逻辑是什么,但我的注释应该会给你一个起点。您需要通过Google了解更多信息 - 如何将用户重定向到不同的视图,或者是否抛出强类型异常,在其他地方处理它(可能在[HandleError]属性中)。


如何实现自己的授权操作过滤器已经在SO上多次回答过了。例如,参见https://dev59.com/iHRC5IYBdhLWcg3wCMrX - bzlm

10

Matt是对的。

授权的目的是为了展示该用户有权执行该功能,而您所尝试做的是判断他们是否能够为特定ID执行该功能。

因此有两种解决方案:

  1. 像Matt说的那样,创建一个不带ID的操作,但是从会话信息中查找当前已登录的用户并获取其信息。
  2. 创建一个需要ID的操作,但只允许管理员访问-这样他们就可以在需要时修改其他用户的信息。

但是要回答问题,授权仅仅是表示“是的,这个人可以使用修改用户操作”,并不基于输入的参数。

另一种方法是您可以使其检查获取到的用户 == 当前用户,或者重定向到另一个操作,表明他们无法编辑该用户-但最好提供一个不带id且仅获取当前已登录用户的操作。


4
解决此问题的方法:http://nerddinnerbook.s3.amazonaws.com/Part9.htm “在编辑晚宴时使用 User.Identity.Name 属性”
现在,让我们添加一些授权逻辑,限制用户只能编辑他们自己主持的晚餐的属性...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接