当站点具有全局AuthorizeAttribute时,ASP.NET允许匿名访问OData $元数据

时间:2016-03-09 14:50:45

标签: asp.net asp.net-web-api odata asp.net-web-api2 odata-v4

我有一个ASP.NET OData站点,在WebApiConfig文件中包含以下内容:

config.Filters.Add(new AuthorizeAttribute())

这会强制所有呼叫者在呼叫任何控制器之前进行身份验证 不幸的是,这也迫使用户身份验证访问“$ metadata”网址 我需要全局强制对所有控制器访问进行身份验证,同时还允许匿名访问“$ metadata”URL。

3 个答案:

答案 0 :(得分:3)

我意识到这个问题已经得到了解答,但我对接受的答案有几点疑虑:

  • 假设元数据端点不会更改
  • 如果添加/移动端点,则需要更新代码
  • 不处理根端点(没有/ $ meatdata)

我同意创建自己的AuthorizeAttribute,但我会以稍微不同的方式实现该方法。

    protected override bool IsAuthorized(HttpActionContext actionContext)
    {
        if (actionContext.ControllerContext.Controller is System.Web.OData.MetadataController)
            return true;

        return base.IsAuthorized(actionContext);
    }

我的解决方案只是检查被访问的控制器是否是OData的MetadataController。如果是,则允许任何人访问,否则,进行正常的授权检查。

答案 1 :(得分:2)

创建一个源自AuthorizeAttribute的自定义过滤器,并覆盖IsAuthorized方法,如下所示:

public class CustomAuthorizationFilter : AuthorizeAttribute
{
    protected override bool IsAuthorized(HttpActionContext actionContext)
    {
        if (actionContext.Request.RequestUri.AbsolutePath == "/$metadata" ||
            actionContext.Request.RequestUri.AbsolutePath == "/%24metadata")
        {
            return true;
        }

        return base.IsAuthorized(actionContext);
    }
}

注册过滤器:

config.Filters.Add(new CustomAuthorizationFilter());

答案 2 :(得分:0)

我想再添加一个选项。如果替换默认的Web API依赖项解析程序(HttpConfiguration.DependencyResolver = YourIDependencyResolver),则可以截取元数据控制器的请求(ODataMetadataController或MetadataController,具体取决于OData库的版本),并将其替换为您自己的实现,如下所示:

[AllowAnonymous, OverrideAuthorization]
public class AnonymousODataMetadataController : ODataMetadataController
{
    protected override void Initialize(HttpControllerContext controllerContext)
    {
        // You must replace the controller descriptor because it appears
        // that the AuthorizeAttribute is pulled from the 
        // controllerContext.ControllerDescriptor.ControllerType (which 
        // is the original type) instead of from controlContext.Controller
        // (which is the type we injected).
        controllerContext.ControllerDescriptor = new HttpControllerDescriptor
        {
            Configuration = controllerContext.Configuration,
            ControllerName = GetType().Name,
            ControllerType = GetType()
        };

        base.Initialize(controllerContext);
    }
}

有关Web API依赖注入系统的信息,请参阅Dependency Injection in ASP.NET Web API 2