MVC configurable Authorization filter

时间:2019-04-23 15:14:57

标签: c# asp.net-mvc authorization authorize-attribute asp.net-authorization

I want to make the [MyAuthorize(Role="R1")] attribute so that "R1" can be made configurable instead of hardcoding on Controller / Action.

The usual approach of creating a [MyAuthorize(Role="R1")] seems to be

public class MyAuthorizeAttribute : AuthorizeAttribute
{
    private readonly string[] _allowedRoles;

    public MyAuthorizeAttribute(params string[] roles)
    {
        this._allowedRoles = roles;
    }
    protected override bool OnAuthorization(AuthorizationContext 
                                             authorizationContext)

    {
        bool authorize = false;

        // Compare current user's Roles with "R1" to figure out if the 
        // Action / Controller can be executed   

        return authorize;
    }
}

But what if Roles like "R1" are subject to change at any time ? i.e., being "R1" one day and being called "AssistantManager" another day.

The application will have to be re-coded to handle this.

I thought of creating a custom [OnAuthorize] attribute that reads (Action/Controller, Role) as key value pairs from the web.config.

Eg:--

  <add key="Controller1" value="Role1" />
  <add key="Action2" value="Role2" />

and in the attribute..

protected override bool OnAuthorization(AuthorizationContext 
                                         authorizationContext)

{
    bool authorize = false;

    // 1. Read all key values 
    // 2. determine Action / Controller the user is trying to go
    // 3. Compare user's roles with those for Action / Controller

    return authorize;
}

I am aware of the limitations of <location .... /> in MVC as per https://stackoverflow.com/a/11765196/807246 and I'm not suggesting that, even though I'm reading from web.config

But what if we read (..and store in session??) all the authorization related configuration when the application first loads up?

Any changes like "R1" -> "AssistantManager" ;; "R2" -> "Manager" should just require a restart of the application, instead of having to make code changes in the controller / action.


I want to know if this is a valid approach or if there are security risks, even with this, and any better alternatives.

1 个答案:

答案 0 :(得分:1)

广告1.您使用配置API阅读设置,例如如果这是常规MVC,则您有ConfigurationManager.AppSettings可以浏览web.config

的“应用设置”部分

广告2。或者您什么都不决定,或者您似乎误解了链接的帖子。您要做的是将Authorize放在要保护的控制器(动作)上,并在执行控制器/动作时触发OnAuthorization。如果确实需要,您可以查看作为参数传递的授权上下文,在路由数据中可以使用控制器和操作。

广告3。这是最简单的部分,当前登录的用户(如果尚未通过身份验证,则为匿名用户)作为authorizationContext.HttpContext.UserIPrincipal属性中传递,因此您甚至可以调用其IsInRole方法。

  

但是如果在应用程序首次加载时我们读取(..并存储在会话中?)所有与授权相关的配置怎么办

您真的不需要。即使您在每次请求时都从配置中读取了配置,但该配置已在每次重新启动应用程序时预加载,您使用ConfigurationManager.AppSettings并不会降低速度。

  

任何更改,例如“ R1”->“ AssistantManager” ;; “ R2”->“ Manager”应该只需要重新启动应用程序,而不必在控制器/操作中进行代码更改。

如果将其存储在配置文件中并对其进行修改会触发应用程序池的重启,那么您无需对代码进行任何更改。

  

我想知道这是否是一种有效的方法,或者是否存在安全风险,即使有这种方法以及其他更好的选择。

存在风险,可以访问您的应用服务器的人可能会重新配置您的应用。但是请注意,这样的人也可能造成其他伤害,例如反编译,修改,重新编译和重新上传您的应用。甚至用其他东西代替它。

关于替代方案,如果更好的标准含糊不清,根本不可能提出更好的方案。如果某些东西可能更好,我们必须知道更好代表什么。

换句话说,这看起来不错。