首页 > 解决方案 > MVC 可配置授权过滤器

问题描述

我想使[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 pairsweb.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;
}

我知道<location .... />在 MVC中的局限性,https://stackoverflow.com/a/11765196/807246 我并不是在暗示,即使我正在阅读web.config

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

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


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

标签: c#asp.net-mvcauthorizationauthorize-attributeasp.net-authorization

解决方案


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

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

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

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

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

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

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

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

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

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

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


推荐阅读