将Func作为属性参数传递以保护MVC路由

jjr*_*527 8 c# asp.net asp.net-mvc attributes

我正在尝试从满足一系列标准的一组用户中保护我的MVC路由.由于MVC似乎使用了很多属性而Steven Sanderson在他的专业MVC书中使用了一个安全可扩展性,因此我开始沿着这条路线前进,但我想根据我应用它的动作来定义规则.

有些行为仅适用于员工,有些则不适用.

有些行为仅适用于company1,有些则不适用.

所以我在想这种用法......

[DisableAccess(BlockUsersWhere = u => u.Company != "Acme")]
public ActionResult AcmeOnlyAction()
{
...
}

[DisableAccess(BlockUsersWhere = u => u.IsEmployee == false)]
public ActionResult EmployeeOnlyAction()
{
...
}
Run Code Online (Sandbox Code Playgroud)

看起来很干净,我真的很容易实现,但我得到以下编译器错误:

'BlockUsersWhere'不是有效的命名属性参数,因为它不是有效的属性参数类型

显然你不能使用Func作为属性参数.有什么其他建议来解决这个问题或其他提供我们在MVC项目中喜欢的简单用法的建议吗?

mar*_*ind 4

Necros 的建议可行,但是您必须SecurityGuard在每个操作方法的主体中调用他的助手。

如果您仍然想使用基于声明性属性的方法(其优点是您可以将属性应用于整个控制器),您可以编写自己的AuthorizeAttribute

public class CustomAuthorizeAttribute : AuthorizeAttribute {
    public bool EmployeeOnly { get; set; }
    private string _company;

    public string Company {
        get { return _company; }
        set { _company = value; }
    }


    protected override bool AuthorizeCore(HttpContextBase httpContext) {
        return base.AuthorizeCore(httpContext) && MyAuthorizationCheck(httpContext);
    }

    private bool MyAuthorizationCheck(HttpContextBase httpContext) {
        IPrincipal user = httpContext.User;

        if (EmployeeOnly && !VerifyUserIsEmployee(user)) {
            return false;
        }

        if (!String.IsNullOrEmpty(Company) && !VerifyUserIsInCompany(user)) {
            return false;
        }

        return true;
    }

    private bool VerifyUserIsInCompany(IPrincipal user) {
        // your check here
    }

    private bool VerifyUserIsEmployee(IPrincipal user) {
        // your check here
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以按如下方式使用它

[CustomAuthorize(Company = "Acme")]   
public ActionResult AcmeOnlyAction()   
{   
...   
}   

[CustomAuthorize(EmployeeOnly = true)]   
public ActionResult EmployeeOnlyAction()   
{   
...   
}  
Run Code Online (Sandbox Code Playgroud)