自定义授权过滤器未传入参数

Custom Authorize filter not getting parameter passed in

我在尝试使用标准授权属性时遇到问题。它似乎只是被忽略了。我试图解决这个问题是自己写的,它被调用但参数没有被传递。

BasicAuthorizeAttribute 的默认构造函数被调用,但从未调用采用字符串参数的构造函数。也调用了 OnAuthorization,但从未设置角色 属性。

尽管 web.config 中的身份验证设置为 None,但我们正在使用 Windows 身份验证。将其更改为 Windows 没有任何区别。

我们正在使用 MVC 5 和 Castle Windsor,我怀疑这是导致我出现问题的原因。

在控制器上以及我有的动作:

[BasicAuthorize(Roles = "Developer")]

属性过滤器

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class BasicAuthorizeAttribute : ActionFilterAttribute, IAuthorizationFilter
{
    public string Roles { get; set; }

    public BasicAuthorizeAttribute()
    {
    }

    public BasicAuthorizeAttribute(string roles)
    {
        Roles = roles;
    }

    public void OnAuthorization(System.Web.Mvc.AuthorizationContext filterContext)
    {
        if (!string.IsNullOrWhiteSpace(Roles))
        {
            // Check user roles here

            // User not in role
            filterContext.Result = new HttpUnauthorizedResult(); // mark unauthorized
        }
    }

    public void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext)
    {
        var user = filterContext.HttpContext.User;
        if (user == null || !user.Identity.IsAuthenticated)
        {
            filterContext.Result = new HttpUnauthorizedResult();
        }
    }
}

温莎城堡布置如下

...
Component.For<FilterAttribute>().ImplementedBy<BasicAuthorizeAttribute>().LifeStyle.PerWebRequest.Named(typeof(BasicAuthorizeAttribute).FullName)
...

在web.config中我们有以下

...
<authentication mode="None" />
...
<modules>
        <remove name="FormsAuthenticationModule" />
</modules>
...

我在这上面花了一天多的时间,Google 不再是我的朋友了。有人对如何解决这个问题有建议吗?或者最好使用默认的 [Authorize(Roles = "...")] 属性?

编辑

我找到了罪魁祸首。以下几行导致了问题。

var oldProvider = FilterProviders.Providers.Single(f => f is FilterAttributeFilterProvider);
FilterProviders.Providers.Remove(oldProvider);

由于您没有提供任何自定义逻辑,您应该只使用 AuthorizeAttribute

[Authorize(Roles = "Developer")]

理想的使用方式是将其注册为全局过滤器。然后您将拥有白名单安全性(默认安全)。

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
        filters.Add(new AuthorizeAttribute());
    }
}

这意味着所有用户都必须登录才能使用任何操作。然后在您的控制器上,您可以按用户或角色覆盖或通过提供 AllowAnonymousAttribute.

public class HomeController : Controller
{
    // Everyone has access
    [AllowAnonymous]
    public ActionResult Index()
    {
        return View();
    }

    // Only logged in users have access
    public ActionResult About()
    {
        ViewBag.Message = "Your application description page.";

        return View();
    }

    // Only admins have access
    [Authorize(Roles = "Admin")]
    public ActionResult Contact()
    {
        ViewBag.Message = "Your contact page.";

        return View();
    }
}

请注意 AuthorizeAttribute 需要某种身份验证系统才能执行任何操作。要使其正常工作,最简单的解决方案是 select Windows 或来自 Visual Studio 的 Web MVC 模板。请注意,最新的 Visual Studio 2015 Community Edition 现在是免费的,其中包含以前免费版本中缺少的许多功能。

至于 DI,属性由 .NET 运行时自动实例化,因此无法直接注入它们。您不应尝试向容器注册 AuthorizeAttribute,因为这样没有意义。

See if you need to customize the AuthorizeAttribute and thus need to actually make a DI-friendly authorization filter.

我找到了罪魁祸首。以下行导致了问题。

var oldProvider = FilterProviders.Providers.Single(f => f is FilterAttributeFilterProvider);
FilterProviders.Providers.Remove(oldProvider);