ASP.NET allow anonymous access to OData $metadata when site has global AuthorizeAttribute

眉间皱痕 提交于 2019-12-11 10:05:47

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!