【问题标题】:MVC configurable Authorization filterMVC 可配置授权过滤器
【发布时间】:2019-09-12 19:49:01
【问题描述】:

我想创建[MyAuthorize(Role="R1")] 属性,以便 "R1" 可以进行配置,而不是在 Controller / Action 上进行硬编码。

创建[MyAuthorize(Role="R1")] 的常用方法似乎是

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;
    }
}

但是如果像"R1" 这样的角色随时可能发生变化怎么办? 即,有一天是"R1",另一天被称为"AssistantManager"

应用程序必须重新编码以处理此问题。

我想创建一个自定义的[OnAuthorize] 属性,该属性读取 (动作/控制器,角色)作为key value pairs 来自web.config

例如:--

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

在属性中..

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;
}

我知道 &lt;location .... /&gt; 在 MVC 中的局限性 根据https://stackoverflow.com/a/11765196/807246 我不是在暗示,即使我正在阅读web.config

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

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


我想知道这是否是一种有效的方法,或者是否存在安全风险,即使这样,以及任何更好的替代方案。

【问题讨论】:

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


    【解决方案1】:

    广告 1. 您使用配置 API 读取设置,例如如果这是常规 MVC,您可以使用 ConfigurationManager.AppSettings 查看 web.config 的应用设置部分

    广告 2。您没有确定任何内容,或者更确切地说,您似乎误解了链接的帖子。您所做的是将Authorize 放在要保护的控制器(操作)上,并在执行控制器/操作时触发OnAuthorization。如果你真的想要,你可以查看作为参数传递的授权上下文,控制器和操作在路由数据中可用。

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

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

    你真的不必。即使您在每次请求时从配置中读取它,但在每次重新启动应用程序时已经预加载了配置,您并不会真正减慢ConfigurationManager.AppSettings 的速度。

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

    如果你将它存储在配置文件中,修改它会触发应用池的重启,你不需要对代码做任何更改。

    我想知道这是否是一种有效的方法,或者是否存在安全风险,即使这样,以及任何更好的替代方案。

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

    至于替代方案,如果更好的标准是模糊的,就完全不可能提出任何更好的。如果某样东西可能更好,我们必须知道更好代表什么。

    简单来说,这看起来不错。

    【讨论】:

    • 感谢您的洞察力。更好,在这里,只是意味着更安全,没有https://stackoverflow.com/a/11765196/807246中提到的风险
    • 正如我所说,声明性web.config 的授权不适用于 MVC 控制器/操作,正如链接帖子中也提到的那样。如果您不确定,请坚持使用基于属性/过滤器的授权。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-27
    • 2011-03-28
    • 2017-04-08
    • 1970-01-01
    • 2015-12-25
    • 2012-07-14
    相关资源
    最近更新 更多