我有一个名为控制器方法Edit
中,用户可以编辑的数据,他们已经像这样创造了...
public ActionResult Edit(int id)
{
Submission submission = unit.SubmissionRepository.GetByID(id);
User user = unit.UserRepository.GetByUsername(User.Identity.Name);
//Make sure the submission belongs to the user
if (submission.UserID != user.UserID)
{
throw new SecurityException("Unauthorized access!");
}
//Carry out method
}
此方法适用罚款不过是有点乱摆在每个控制器编辑方法。 每个表始终有一个UserID
,所以我想知道是否有通过自动执行此更简单的方法[Authorize]
属性或一些其他机制来使代码更干净。
是的,你可以做到这一点通过自定义授权属性:
public class MyAuthorizeAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
var authorized = base.AuthorizeCore(httpContext);
if (!authorized)
{
return false;
}
var rd = httpContext.Request.RequestContext.RouteData;
var id = rd.Values["id"];
var userName = httpContext.User.Identity.Name;
Submission submission = unit.SubmissionRepository.GetByID(id);
User user = unit.UserRepository.GetByUsername(userName);
return submission.UserID == user.UserID;
}
}
然后:
[MyAuthorize]
public ActionResult Edit(int id)
{
// Carry out method
}
让我们假设你需要养活,我们提取到自定义属性的动作参数此提交实例,以避免击中数据库再次,你可以做到以下几点:
public class MyAuthorizeAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
var authorized = base.AuthorizeCore(httpContext);
if (!authorized)
{
return false;
}
var rd = httpContext.Request.RequestContext.RouteData;
var id = rd.Values["id"];
var userName = httpContext.User.Identity.Name;
Submission submission = unit.SubmissionRepository.GetByID(id);
User user = unit.UserRepository.GetByUsername(userName);
rd.Values["model"] = submission;
return submission.UserID == user.UserID;
}
}
然后:
[MyAuthorize]
public ActionResult Edit(Submission model)
{
// Carry out method
}
我建议你拉出来的逻辑动作/控制器,并建立一个域类来处理逻辑。
操作方法真的应该只处理从得到的数据和发送数据到视图。 你可以创建一些通用的,足以应付您的需求,也将遵循单一的责任主体。
public class AuthorizedToEdit
{
protected override bool AuthorizeCore(string user, int itemId)
{
var userName = httpContext.User.Identity.Name;
var authUsers = SubmissionRepository.GetAuthoriedUsers(itemId);
return authUsers.Contains(user);
}
}
这也将让您可以灵活后来就允许类似于admin用户
@if (Request.IsAuthenticated && User.IsInRole("Student"))
{
@Html.ActionLink("Edit", "Edit", new { id = item.StdID })
}
在我的情况下,用户的loggedIn是学生。 所以我说,如果登录请求进行认证,如果他的角色是学生,然后让链接编辑是他访问。
下面这使您可以让普通用户或管理员进行编辑也。
@if(Request.IsAuthenticated && User.IsInRole("Student") ||
User.IsInRole("Administrator"))
{
@Html.ActionLink("Edit", "Edit", new { id = item.StdID })
}
我建议在阅读了AuthorizeAttribute
(见这里 )。 此外,你见过这个帖子? 它提供了如何重写认证属性内脏以及如何使用的IPrincipal和IIdentity的。