结合自定义AuthorizeAttribute和RequireHttpsAttribute

时间:2016-01-07 15:30:05

标签: c# asp.net-mvc asp.net-mvc-5

我在RequireHttpsAttribute中应用了自定义AuthorizeAttribute和自定义FilterConfig,以确保所有控制器都以相同的方式使用HTTPS和授权。

我还有一个需要其他授权的控制器操作。在这种情况下,我必须首先使用[OverrideAuthorization]覆盖全局授权过滤器,然后我可以为此操作设置特殊授权。

[OverrideAuthorization]也会覆盖CustomRequireHttpsAttribute,因为IAuthorizationFilter也是如此。CustomRequireHttpsAttribute。我可以做什么,以便每次覆盖授权时都不必读取public class FilterConfig { public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new CustomRequireHttpsAttribute()); filters.Add(new CustomAuthorizeAttribute(Role = "User")); } } public class MyController : BaseController { public ActionResult DoSomeUserStuff() { } [OverrideAuthorization] [CustomRequireHttpsAttribute] [CustomAuthorizeAttribute(Role = "Admin")] public ActionResult DoSomeAdminStuff() { } } 属性?

CartItem

2 个答案:

答案 0 :(得分:1)

我最终根据this帖子的修改版本创建了自己的自定义IFilterProvider

我添加了一个额外的属性,我可以用于那些控制器或操作,我想覆盖全局设置的属性。它除了扩展CustomAuthorizeAttribute以外它没有任何其他功能,因此它具有相同的功能:

public class OverrideCustomAuthorizeAttribute : CustomAuthorizeAttribute {}

然后我创建了一个IFilterProvider,用于检查过滤器列表中是否存在任何OverrideCustomAuthorizeAttribute个。如果是,请从列表中删除所有CustomAuthorizeAttribute

public class CustomFilterProvider : IFilterProvider
{
    private readonly FilterProviderCollection _filterProviders;

    public CustomFilterProvider(IList<IFilterProvider> filters)
    {
        _filterProviders = new FilterProviderCollection(filters);
    }

    public IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
    {
        var filters = _filterProviders.GetFilters(controllerContext, actionDescriptor).ToArray();

        var shouldOverrideCustomAuthorizeAttribute = filters.Any(filter => filter.Instance is OverrideCustomAuthorizeAttribute);
        if (shouldOverrideCustomAuthorizeAttribute)
        {
            // There is an OverrideCustomAuthorizeFilterAttribute present, remove all CustomAuthorizeAttributes from the list of filters
            return filters.Where(filter => filter.Instance.GetType() != typeof(CustomAuthorizeAttribute));
        }

        return filters;
    }
}

我在IFilterProvider注册了Global.asax.cs

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        // Some other stuff first....

        var providers = FilterProviders.Providers.ToArray();
        FilterProviders.Providers.Clear();
        FilterProviders.Providers.Add(new CustomFilterProvider(providers));
    }
}

我在CustomAuthorizeAttribute注册全球FilterConfig.cs,就像之前一样:

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new CustomRequireHttpsAttribute());
        filters.Add(new CustomAuthorizeAttribute(Role = "User"));
    }
}

不同之处在于我在控制器中使用OverrideCustomAuthorizeAttribute

public class MyController : BaseController
{
    public ActionResult DoSomeUserStuff()
    {
    }

    [OverrideCustomAuthorizeAttribute(Role = "Admin")]
    public ActionResult DoSomeAdminStuff()
    {
    }
}

这样,CustomRequireHttpsAttribute始终全局设置,永不覆盖。

答案 1 :(得分:0)

根据this page,您可以在OverrideAuthorizationAttribute.FiltersToOverride Property中指定要覆盖的过滤器。

CanActivate