我有以下数据库结构 我必须为ASP.NET MVC 5站点构建身份验证/授权。
数据库架构的工作方式如下:每个user
属于group
,每个group
可以被授予/拒绝permission
。每个权限都与控制器上的操作相匹配(例如,Petitions
控制器将执行以下操作:List
,View
,Add
,{{1 },Edit
,Delete
,VoteFor
,VoteAgainst
和Reject
,每个操作都是Approve
表中的一个条目。 / p>
所有这一切的目的是,每次用户调用某个操作时,该站点都会验证该用户是否属于已被授予该操作权限的组,并做出相应的反应。
示例:我们假设管理员授予Permissions
组PetitionsList
,PetitionsView
,PetitionsApprove
和PetitionsReject
权限,以及Managers
,PetitionsList
,PetitionsView
,PetitionsAdd
和PetitionsVoteFor
到PetitionsVoteAgainst
群组。
在这种情况下,两个小组都可以
经理可以
但他们无法
以同样的方式,用户可以
但他们不能:
并且都不能编辑或删除请愿书。
我真的很想利用MVC 5中的属性功能。我的想法是构建自定义属性,在幕后执行所有身份验证/授权。像这样:
Users
请注意每个操作的public class PetitionsController : Controller
{
[MyCustomAuth(Permission="PetitionsList",Groups="Users,Managers")]
public ActionResult List()
{
//show the list of petitions
}
[MyCustomAuth(Permission="PetitionsView",Groups="Users,Managers")]
public ActionResult View()
{
//show a specific petition
}
[MyCustomAuth(Permission="PetitionsAdd",Groups="Users")]
public ActionResult Add()
{
//show add petition form
}
[HttpPost]
[MyCustomAuth(Permission="PetitionsAdd",Groups="Users")]
public ActionResult Add(object[] params)
{
//save new petition
}
[MyCustomAuth(Permission="PetitionsEdit",Groups="Admins")]
public ActionResult Edit(int id)
{
//show edit petition form
}
[HttpPost]
[MyCustomAuth(Permission="PetitionsEdit",Groups="Admins")]
public ActionResult Edit(object[] params)
{
//save changes to petition
}
[HttpPost]
[MyCustomAuth(Permission="PetitionsDelete",Groups="Admins")]
public ActionResult Delete(int_id)
{
//delete petition
}
[HttpPost]
[MyCustomAuth(Permission="PetitionsVoteFor",Groups="Users")]
public ActionResult VoteFor(int id)
{
//add vote supporting petition
}
[HttpPost]
[MyCustomAuth(Permission="PetitionsVoteAgainst",Groups="Users")]
public ActionResult VoteAgainst(int id)
{
//add vote against petition
}
[HttpPost]
[MyCustomAuth(Permission="PetitionsApprove",Groups="Managers")]
public ActionResult Approve(int id)
{
//approve petition
}
[HttpPost]
[MyCustomAuth(Permission="PetitionsReject",Groups="Managers")]
public ActionResult Reject(int id)
{
//reject petition
}
}
属性。如果用户实际上有权在幕后执行该操作,那么我希望该属性能够做大量工作。当然,如果它未经过身份验证/授权,该属性应该重定向到登录页面/ 401 /其他地方。
我的问题是,我从哪里开始?我是否希望从MVC 5中的某些类实现一些特殊的接口/继承?或者我是否必须从头开始写这个?
另外,请提前感谢阅读这一文本墙并向我提供正确方向的提示/指示。
答案 0 :(得分:1)
我认为你可以从下面的自定义授权过滤器开始。它还处理两者的情况 - ajax请求和整页请求。
public class MyCustomAuthAttribute : FilterAttribute, IAuthorizationFilter
{
public string Permission { get; set; }
public string Groups { get; set; }
public void OnAuthorization(AuthorizationContext filterContext)
{
bool isauthorized = CheckIfUserIsAuthorized();
if (!isauthorized)
context.Result = new HttpUnauthorizedResult(); // mark unauthorized
// Only do something if we are about to give a HttpUnauthorizedResult and we are in AJAX mode.
if (filterContext.Result is HttpUnauthorizedResult && filterContext.HttpContext.Request.IsAjaxRequest())
{
filterContext.Result = new JsonResult
{
Data = new { Success = false, Message = "Unauthorized Access" },
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
else
{
base.OnAuthorization(filterContext);
if (filterContext.Result is HttpUnauthorizedResult)
{
HttpContext.Current.Session.Abandon();
System.Web.Security.FormsAuthentication.SignOut();
filterContext.Result = new RedirectResult("Your Login Page.");
}
}
}
private bool IsAuthorizedUser()
{
// use Permission, Groups and your logic
}
}
并按照您提到的方式使用它:
[MyCustomAuth(Permission="PetitionsEdit",Groups="Admins")]