How to prevent unauthorized child action to return 401

耗尽温柔 提交于 2019-12-11 06:27:12

问题


Problem

Long story short, how can you prevent unauthorized ChildActions to return a 401 code and return an empty result instead.

Context

My application uses NTLM to authenticate on the network. I also want to handle anonymous identification, for non NTLM capable devices or if someone goes through some proxy.

One the the web application, there is controller/actions that absolutely require to be logged in to be viewable and some other that are viewable as anonymous. For the ones that authentication is mandatory where I initially used the following:

[Authorize()]
public class SomeController : BaseController

Which works as expected and returns a 401 Status Code (Unauthorized).

The problem starts on the page that allows anonymous. Because those pages have parts that uses RenderAction to render pieces that requires authentication.

On local developpement server on front end everything looks fine, but with IIS any page that have any small piece that requires authentication it returns 401 page. So I created a custom Authorize attribute:

public class CustomAuthorizeAttribute : AuthorizeAttribute
{
    public bool Ignore401ChildAction { get; set; }

    public CustomAuthorizeAttribute()
        : base() {
        this.Ignore401ChildAction = true;
    }

    protected override void HandleUnauthorizedRequest( AuthorizationContext filterContext ) {
        base.HandleUnauthorizedRequest( filterContext );
        if( this.Ignore401ChildAction && filterContext.IsChildAction ) {
            filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
        }
    }
}

And then on frontend it seems to produce correct behavior with and without IIS. However in the backend, even if the page renders completly it returns a 401

So I added the following to my CustomAttribute instead of TrySkipIisCustomErrors

filterContext.HttpContext.Response.StatusCode = 200;
filterContext.Result = new EmptyResult();

In anonymous everything is fine, but when NTLM is enabled server doesn't request authentication when the controller doesnt have that CustomAuthorize attribute. It seems like its only requesting the crendetials when their mandatory instead of when they're available.

Thank you,

EDIT

After lot of searching, digging and fiddling, realized that true problem is that Anonymous identification will take precedence over Windows/NTLM. If Anonymous and Windows authentication are enabled, Windows will only execute if anonymous authentication fails.

SOLUTION

(not perfect and kind of hackish but it works)

Add the following function to your BaseController then call from the views that do not mandatory require authentication, or simply call it from your _Layout view.

NOTE: Even though page will render correctly as anonymous, a 401 status code will still be returned.

[CustomAuthorize]
public ActionResult Auth() {
    return new EmptyResult();
}

来源:https://stackoverflow.com/questions/12091116/how-to-prevent-unauthorized-child-action-to-return-401

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