在自定义控制器工厂中进行通用授权的良好做法?

时间:2011-03-18 22:53:12

标签: asp.net-mvc

我的控制器共享客户端ID。路线:

clients/{clientId}/{controller}/{action}/{id}

示例网址:

clients/1/orders/details/1
clients/2/children/index
clients/2/cars/create

您需要为客户提供适当的授权。我不想在每个控制器中执行相同的客户端授权。我提出了在这样的自定义控制器工厂中进行自动化的想法:

public class CustomControllerFactory : DefaultControllerFactory
{
    private readonly IAuthService _authService;

    public CustomControllerFactory(IAuthService authService)
    {
        _authService = authService;
    }

    protected override IController GetControllerInstance(
        RequestContext requestContext, Type controllerType)
    {
        var doAuth = requestContext.RouteData.Values.ContainsKey("clientId");
        if (doAuth)
        {
            var principal = requestContext.HttpContext.User;
            var clientId = long.Parse(
                requestContext.RouteData.Values["clientId"].ToString());
            var authorized = _authService.Client(principal, clientId);
            if (!authorized)
            {
                return new AuthController();
            }                
        }
        return base.GetControllerInstance(requestContext, controllerType);
    }
}

你认为这是一个好习惯吗?为什么呢?

3 个答案:

答案 0 :(得分:4)

不,我认为这不是一个好习惯。自定义AuthorizeAttribute似乎更适合处理授权而不是控制器工厂。

答案 1 :(得分:0)

当您的应用程序具有非常强大的多租户或用户所有权模型时,这是绝对最佳的做法。

[Authorize]属性,即使在类级别上,如果要使用它们装饰大部分应用程序,也只是混乱。 [Authorize]属性也可能被遗忘。你的技术将始终有效。

答案 2 :(得分:0)

我们已经使用以下概念来检查授权;

步骤1:需要创建3个不同的表并输入适当的数据;

一个。表:操作

ID:INT,PK 控制器:VARCHAR(100) 行动:VARCHAR(100) 列举HTTPMethod:VARCHAR(10)

B中。表:许可

Id:int,PK 名称:varchar(100)

℃。表:Permission_Action

编号:INT,PK PermissionId:int,FK ActionId:int,FK

步骤2:创建一个将继承自“Controler”类的ApplicationController,并且所有其他控制器应继承自“ApplicationController”而不是“Controller”。

//Declaration of ApplicationController
public class ApplicationController : Controller
//Declaration of Other controller
public class OtherController : ApplicationController 

步骤3:对于持久性,在身份验证后获取当前用户的所有控制器和操作。我们每次都可以激活SQL查询。

步骤4:在“OnActionExecuting”方法中,您将获得有关当前请求的控制器和操作的信息。查看在步骤3中获取的控制器操作列表,以找出当前控制器和操作。

 string controller = filterContext.RouteData.Values["controller"] as string;
 string action = filterContext.RouteData.Values["action"] as string;
 string httpMethod = filterContext.HttpContext.Request.HttpMethod.ToLowerInvariant();

步骤5:如果找到,则用户有权继续执行操作,否则返回预定义的“SecurityResult”

示例:

注意:与“授权”相关的操作应在创建用户时分配。此部分不包括此部分;

一个。行动表数据:

{1, “雇员”, “详细信息”, “获取”},{2, “雇员”, “创建”, “获取”},{3, “雇员”, “创建”, “后”} ,{4, “雇员”, “删除”, “后”}

B中。权限表数据:

{1,“查看员工明细”},{2,“创建员工明细”},{3,“删除员工明细”}

℃。 Permission_Action表数据:

{1,1,1},{1,2,2},{1,2,3},{1,3,4}

d。现在,用户“vrluckyin”仅具有查看数据和创建员工的权限。

尚未分配“员工”中的“删除”操作。

授权后,如果“vrluckyin”用户尝试调用“Employee”控制器的“删除”操作,则系统将返回安全视图而不是删除视图。

  • 无需在每个操作上编写[Authorize]属性。
  • 我们可以轻松添加/删除/更新用户权限。只有数据库更改!!!

享受!