现在我有以下网站结构:
前端:网站\用户1,网站\用户2
后端:website \ account \ user1,website \ account \ user2
其中website \ account控制器已应用通用 [授权] 属性。这还不够,因为任何授权用户只需访问website \ account \ url(如果他知道他的名字)就可以访问其他用户支持的功能。
解决此问题的最佳方法是什么?
到目前为止我有两种方法:
创建自定义Authorize属性,检查控制器上下文,从中提取用户信息并将其与ASP.NET中当前授权用户进行比较:
var currerntUserId = (long)System.Web.Security.Membership.GetUser().ProviderUserKey;
return ExtractCurrentUserId(filterContext) == currerntUserId;
答案 0 :(得分:2)
这个怎么样?
路线/网站/我的帐户
[Authorize]
public class MyAccountController : Controller
{
public ActionResult Index()
{
var userData = System.Web.Security.Membership.GetUser();
// note you could also get this from db using this.User.Identity.Name
return View(userData);
}
}
以这种方式控制授权要容易得多,因为我们没有通过路由参数将userid传递给action方法。某人可以访问特定用户帐户的后端的唯一方法是以该用户身份登录。
回复评论:
在评论中回答你的问题是什么更容易/更难/更好/我的偏好是什么,我将继续做出最终答案“这取决于。”
这取决于数据的敏感性,管理员可以做什么事情,不允许用户(反之亦然),需要保护多少控制器操作,视图对于public / account / admin的相似程度关于数据等的观点。你问题中陈述的几乎所有内容以及这里的所有答案都是有效的方法。您当然可以使用ActionFilter并保留用户URL,或者您可以直接在action方法中执行此操作(如果没有很多),更改URL架构,实现模拟(或不实现)等。
答案 1 :(得分:0)
当您从数据存储区(很可能是数据库)检索用户数据时,您应该只检索经过身份验证的用户的用户名的数据。在您的控制器中,这将为您提供当前经过身份验证的用户的用户名:
User.Identity.Name
所以你可以这样做:
return ExtractCurrentUserId(filterContext) == User.Identity.Name;
答案 2 :(得分:0)
如果您使用基于角色的身份验证与SimpleMembership,您可以执行类似的操作,并为用户提供应该能够访问某些控制器操作的角色:
public class MyAccountController : Controller
{
[Authorize(Roles = "Admin")]
public ActionResult User1()
{
// do user1 work
}
[Authorize]
public ActionResult User2()
{
// do user2 work
}
}