1

在我的 .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。如果你想知道我为什么要发送虚拟参数,你可以看看这里这里

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

找不到克服它的方法(我对想法持开放态度),我想知道安装新的 2.0 beta 版本是否可以解决这个问题。

有任何想法吗?

4

1 回答 1

0

目前无法对 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);
});
于 2013-04-17T09:45:06.343 回答