【问题标题】:FluentSecurity 2.0 support for action with parametersFluentSecurity 2.0 支持带参数的操作
【发布时间】:2013-04-15 09:52:06
【问题描述】:

在我的 .net mvc 4 应用程序中,我使用最新版本的 FluentSecurity (1.4) 来保护我的操作。

这是一个说明我的问题的例子:

假设我有一个具有 2 个编辑操作(获取和发布)的控制器:

    public class MyController : Controller
{
    //
    // GET: /My/

    public ActionResult Edit(decimal id)
    {
        var modelToReturn = GetFromDb(id);
        return View(modelToReturn);
    }

    [HttpPost]
    public ActionResult Edit(MyModel model)
    {
        Service.saveToDb(model);
        return View(model);
    }

}

现在,我想为每个操作设置不同的安全策略。为此,我定义(使用流利的安全性):

    configuration.For<MyController>(x => x.Edit(0))
                                         .AddPolicy(new MyPolicy("my.VIEW.permission"));
    configuration.For<MyController>(x => x.Edit(null))
                                         .AddPolicy(new MyPolicy("my.EDIT.permission"));

第一个配置是get,第二个是post。 如果你想知道我为什么要发送虚拟参数,你可以看看 here 和 here。

问题是流畅的安全性无法区分这两者之间的区别,因此这不起作用。

找不到克服它的方法(我愿意提出想法),我想知道安装 new 2.0 beta release 是否可以解决这个问题。

有什么想法吗?

【问题讨论】:

    标签: asp.net-mvc-4 fluent-security


    【解决方案1】:

    目前无法对 FluentSecurity 中的每个签名应用不同的策略。 这是因为 FluentSecurity 无法知道 ASP.NET MVC 将调用哪个签名。它所知道的只是动作的名称。因此 FluentSecurity 必须将两个动作签名视为一个动作。

    但是,您可以将多个策略应用于同一操作(您不限于每个操作只有一个策略)。有了这个,您可以为每个策略应用一个 Http 动词过滤器。以下是它的外观示例:

    1) 创建一个可以继承的基本策略

    public abstract class HttpVerbFilteredPolicy : ISecurityPolicy
    {
        private readonly List<HttpVerbs> _httpVerbs;
    
        protected HttpVerbFilteredPolicy(params HttpVerbs[] httpVerbs)
        {
            _httpVerbs = httpVerbs.ToList();
        }
    
        public PolicyResult Enforce(ISecurityContext securityContext)
        {
            HttpVerbs httpVerb;
            Enum.TryParse(securityContext.Data.HttpVerb, true, out httpVerb);
    
            return !_httpVerbs.Contains(httpVerb)
                ? PolicyResult.CreateSuccessResult(this)
                : EnforcePolicy(securityContext);
        }
    
        protected abstract PolicyResult EnforcePolicy(ISecurityContext securityContext);
    }
    

    2) 创建您的自定义政策

    public class CustomPolicy : HttpVerbFilteredPolicy
    {
        private readonly string _role;
    
        public CustomPolicy(string role, params HttpVerbs[] httpVerbs) : base(httpVerbs)
        {
            _role = role;
        }
    
        protected override PolicyResult EnforcePolicy(ISecurityContext securityContext)
        {
            var accessAllowed = //... Do your checks here;
            return accessAllowed
                ? PolicyResult.CreateSuccessResult(this)
                : PolicyResult.CreateFailureResult(this, "Access denied");
        }
    }
    

    3) 将当前请求的 HTTP 动词添加到 ISecurityContext 的 Data 属性并保护您的操作

    SecurityConfigurator.Configure(configuration =>
    {
        // General setup goes here...
    
        configuration.For<MyController>(x => x.Edit(0)).AddPolicy(new CustomPolicy("my.VIEW.permission", HttpVerbs.Get));
        configuration.For<MyController>(x => x.Edit(null)).AddPolicy(new CustomPolicy("my.EDIT.permission", HttpVerbs.Post));
    
        configuration.Advanced.ModifySecurityContext(context => context.Data.HttpVerb = HttpContext.Current.Request.HttpMethod);
    });
    

    【讨论】:

    • Kristoffer,这听起来是一个有趣的解决方法,我一定会试一试并更新您。谢谢!!!
    • 行配置.Advanced.ModifySecurityContext(context => context.Data.HttpVerb = HttpContext.Current.Request.HttpMethod);指的是2.0版吧?它不适用于 1.4(如果我错了,请纠正我)
    • 是的,没错。上面的代码仅适用于 FluentSecurity 2.0。可以用 1.4 做类似的事情,但我还是建议升级。
    • 最终我实现了自己的自定义过滤器。我会接受你的回答,因为我相信它可以解决问题,以防有人使用 Fluent Security 2.0 版。谢谢:)
    猜你喜欢
    • 1970-01-01
    • 2017-01-28
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多