ASP.NET 当站点具有全局 AuthorizeAttribute 时允许匿名访问 OData $metadata
ASP.NET allow anonymous access to OData $metadata when site has global AuthorizeAttribute
我有一个 ASP.NET OData 站点,其 WebApiConfig 文件中包含以下内容:
config.Filters.Add(new AuthorizeAttribute())
这会强制所有调用者在调用任何控制器之前进行身份验证。
不幸的是,这也强制用户身份验证访问“$metadata”url.
我需要全局强制对所有控制器访问进行身份验证,同时还允许匿名访问“$metadata”url。
创建一个派生自 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());
我知道这个问题已经得到解答,但我对已接受的答案有几点疑虑:
- 假设元数据端点不会改变
- 如果端点是 added/moved
,则需要更新代码
- 不处理根端点(没有/$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。如果是,允许任何人访问,否则,通过正常的授权检查。
我想再添加一个选项。如果替换默认的 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。
我有一个 ASP.NET OData 站点,其 WebApiConfig 文件中包含以下内容:
config.Filters.Add(new AuthorizeAttribute())
这会强制所有调用者在调用任何控制器之前进行身份验证。
不幸的是,这也强制用户身份验证访问“$metadata”url.
我需要全局强制对所有控制器访问进行身份验证,同时还允许匿名访问“$metadata”url。
创建一个派生自 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());
我知道这个问题已经得到解答,但我对已接受的答案有几点疑虑:
- 假设元数据端点不会改变
- 如果端点是 added/moved ,则需要更新代码
- 不处理根端点(没有/$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。如果是,允许任何人访问,否则,通过正常的授权检查。
我想再添加一个选项。如果替换默认的 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。