我有以下内容: -
我正在使用Asp.net MVC4启用Windows身份验证的资产管理系统。
系统允许指定一组用户可以执行的操作(例如,某些组可以拥有添加新物理资产的权限,而他们只能读取某些逻辑资产,等等)。
所以我发现使用内置的Asp.net角色管理,不会让我拥有我想要的灵活性。所以我决定做以下事情: -
在Car model object
我将创建一个新的辅助方法
Public bool HaveReadPermison(string userName) {
//check if this user is within a group than have Read permission on CARS, //OR is within a GROUP THAT HAVE HIGHER PERMISON SUCH AS EDIT OR ADD OR //DELETE.
}
接下来,在Action方法中,我将通过调用操作方法来检查用户是否具有读取权限: -
public ActionResult ViewDetails(int id) { // to view transportation asset type
Car car = repository.GetCar(id);
if (!car.HaveReadPermision(User.Identity.Name)) {
if (car == null)
return View("NotFound");
else
return View(car);
}
else
return view (“Not Authorized”);
如果我的方法有效或者它会引起我不知道的问题,那么任何人都可以提出建议。 此致
答案 0 :(得分:1)
在我看来,一旦您决定使用ASP成员资格和角色提供者,您可以继续利用它们进行授权,只需使用Authorize
属性即可。这也将允许通过用户名和角色限制访问。
该属性不会执行基于操作的授权。在这种情况下,有一些选项,但在我看来,松散地基于以下代码可以通过自定义操作过滤器轻松解决:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class CheckUserPermissionsAttribute : ActionFilterAttribute
{
public string Model { get; set; }
public string Action { get; set; }
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var user = filterContext.HttpContext.User.Identity.Name; // or get from DB
if (!Can(user, Action, Model)) // implement this method based on your tables and logic
{
filterContext.Result = new HttpUnauthorizedResult("You cannot access this page");
}
base.OnActionExecuting(filterContext);
}
}
是的,它模糊地启发了CanCan,这对于这类事物来说是一个很好的Ruby宝石。
如果指定了登录页面,则返回Unauthorized (401)
还将指示您的服务器重定向到登录页面。如果要在其他位置重定向,可能需要处理该逻辑。在这种情况下,你应该这样做:
filterContext.Result = new RedirectToRouteResult(new System.Web.Routing.RouteValueDictionary { { "Controller", "Home" }, { "Action", "Index" } });
并选择适当的控制器/操作对。
您可以使用以下属性:
[CheckUserPermissions(Action = "edit", Model = "car")]
public ActionResult Edit(int id = 0)
{
//..
}
请告诉我这是否适合您。
答案 1 :(得分:1)
您采取的方法看似合理,但我会添加一些更改:
最好分开保存授权逻辑。例如,您可以在您的存储库上创建一个装饰器,它将检查当前用户的权限:
public class AuthorizationDecorator: IRepository
{
public AuthorizationDecorator(IRepository realRepository, IUserProvider userProvider)
{
this.realRepository = realRepository;
this.userProvider = userProvider;
}
public Car GetCar(int id)
{
if(this.UserHaveReadPermission(this.userProvider.GetUserName(), Id))
{
return this.realRepository.GetCar(id);
}
else
{
throw new UserIsNotAuthorizedException();
}
}
private bool UserHaveReadPermission(string username, int id)
{
//do your authorization logic here
}
}
IUserProvider将从httpRequest返回curent用户名。 在进行更改后,您无需在编写操作
时担心授权