【问题标题】:Custom Authorize filter not getting parameter passed in自定义授权过滤器没有传入参数
【发布时间】:2015-11-21 16:00:50
【问题描述】:

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

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

尽管在 web.config 中将身份验证设置为无,但我们正在使用 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);

【问题讨论】:

  • 您使用的是默认动作调用程序吗? Windsor 不会创建您的属性。动作调用者将
  • 我根本不认识温莎。我如何知道它是否使用了默认的动作调用程序?正在调用该属性,断点被命中。它只是没有传递参数。
  • 温莎这里根本不涉及
  • 如果我删除 Windsor 的“Component.For()...”代码,那么我的属性将被完全忽略并且断点不会命中
  • 拆除温莎城堡后一切正常。所以这一定是设置错误的地方。感谢您的帮助。

标签: asp.net-mvc-5 castle-windsor custom-attributes


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    由于您没有提供任何自定义逻辑,您应该只使用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 需要某种身份验证系统才能执行任何操作。要使其正常工作,最简单的解决方案是从 Visual Studio 中选择 Windows 或 Web MVC 模板。请注意,最新的Visual Studio 2015 Community Edition 现在是免费的,并且包含许多以前免费版本所缺少的功能。

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

    如果您需要自定义 AuthorizeAttribute 并因此需要实际制作一个对 DI 友好的授权过滤器,请参阅this answer

    【讨论】:

    • 感谢您的详细解答。问题是 Authorize 属性被完全忽略。如果我自己编写并在 Castle Windsor 中设置它们,那么它们可以工作,但不会设置 Roles 属性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-26
    • 2017-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 1970-01-01
    相关资源
    最近更新 更多