问题
I have an ASP.NET OData site that has the following in the WebApiConfig file:
config.Filters.Add(new AuthorizeAttribute())
This forces all callers to authenticate before calling any of the controllers.
Unfortunately, this also forces user authentication to access the "$metadata" url.
I need to globally force authentication for all controller access while also allowing anonymous access the the "$metadata" url.
回答1:
Create a custom filter that derives from AuthorizeAttribute
and override the IsAuthorized
method as follows:
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);
}
}
Register the filter:
config.Filters.Add(new CustomAuthorizationFilter());
回答2:
I realize this question has already been answered, but I have a couple concerns with the accepted answer:
- Assumes the metadata endpoint will not change
- Requires updating the code if an endpoint is added/moved
- Does not handle the root endpoint (without /$meatdata)
I agree with creating your own AuthorizeAttribute
, but I would implement the method a little differently.
protected override bool IsAuthorized(HttpActionContext actionContext)
{
if (actionContext.ControllerContext.Controller is System.Web.OData.MetadataController)
return true;
return base.IsAuthorized(actionContext);
}
My solution simply checks to see if the controller being accessed is OData's MetadataController. If it is, allow anyone access, otherwise, go through the normal authorization checks.
回答3:
I wanted to add one more option. If you replace the default Web API dependency resolver (HttpConfiguration.DependencyResolver = YourIDependencyResolver) you can intercept the request for the metadata controller (ODataMetadataController or MetadataController, depending on the version of the OData library) and replace it with your own implementation, like below:
[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);
}
}
See Dependency Injection in ASP.NET Web API 2 for info about the Web API dependency injection system.
来源:https://stackoverflow.com/questions/35894875/asp-net-allow-anonymous-access-to-odata-metadata-when-site-has-global-authorize