我正在创建一个具有用户概念的asp.net mvc应用程序。每个用户都可以编辑自己的个人资料。例如:
没有什么特别令人兴奋的......
但是,我在授权方案中遇到了一些麻烦。现在系统中只有两个角色,“管理员”和“默认用户”,但未来可能会有更多。
我无法使用常规的Authorize属性来指定授权,因为两个用户都处于相同的角色(即“DefaultUser”)。
所以,如果我像这样指定授权过滤器:
[Authorize(Roles = "DefaultUser")]
然后没有效果。 PersonID = 1可以进入并编辑自己的个人资料(因为他们应该可以),但他们也可以将URL更改为http://localhost/person/edit/2,并且他们也可以完全访问编辑PersonID = 2的个人资料(他们不应该这样做。)
这是否意味着我必须创建自己的授权过滤器,在允许用户访问之前检查用户请求的操作是否“属于”他们?也就是说,如果当前登录的人正在请求参数= 1的编辑操作,是否需要进行自定义检查以确保当前登录的人员是PersonID = 1,如果是,则授权他们,如果没有,拒绝访问?
感觉我在这里遗漏了一些明显的东西,所以任何指导都会受到赞赏。
答案 0 :(得分:62)
也许您可以组织控制器操作,使URL更像http://localhost/person/editme,并显示当前登录用户的编辑表单。这样,用户就无法破解URL来编辑其他人。
答案 1 :(得分:36)
我的$ .02:
授权&认证是两件不同的事情。简单地说,问题是你可以做这件事你应该这样做吗?你可以挑选你的朋友,你可以抠鼻子,但你不能挑选你的朋友鼻子!如果每个角色都可以做到(用户有手和鼻子),则无需检查授权。有一个Post方法供用户访问他们自己的个人资料并测试个人资料ID与表单的隐藏值或重定向(不是你的鼻子,离开)。
有一个Get方法来编辑其他个人资料,只是在这里检查管理员角色 - (我是一名医生,我有权将事情贴在你的鼻子上)......
答案 2 :(得分:16)
更优雅的解决方案是编写自己的授权操作过滤器,方法是扩展[授权]或实施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]属性中)。
答案 3 :(得分:10)
马特是对的。
授权的目的是表明他们被允许执行该功能 - 您要做的是说他们是否可以执行该特定ID的功能。
所以有两个解决方案:
但是要回答这个问题,授权只是说“是的,这个人可以使用修改用户操作”,而不是基于输入的参数。
另一种方式是,您可以检查用户是否检索了==当前用户,或者重定向到另一个操作,说他们无法编辑该用户 - 但最好提供一个不会执行操作的操作取一个id,然后获取当前登录的用户。
答案 4 :(得分:4)
此问题的解决方案:http://nerddinnerbook.s3.amazonaws.com/Part9.htm
“编辑晚餐时使用User.Identity.Name属性
现在让我们添加一些限制用户的授权逻辑,以便他们只能编辑他们自己托管的晚餐的属性......“