This project has moved. For the latest updates, please go here.

Suppress Login Redirect With 401 Response Using WsFederationAuthentication

Dec 8, 2014 at 4:27 PM
I'm using WSFederation and JWT tokens (WsFed for MVC and JWT for WebAPI).
I get a redirect to the SSO site from within my MVC views and not from my WebAPI as I would expect.

The problem I'm having is supressing the 401 redirect when loading a partial view via Jquery Ajax. I want to be able to catch the 401 status code and then update the page accordingly. Is there an attribute or filter I can use to supress WsFed redirection for specific Controllers or Actions?

I'm guessing I need to do something in RedirectToIdentityProvider under the WsFederationAuthenticationNotifications, I'm just not sure what
RedirectToIdentityProvider = context =>
                        {
                            if(IsAjaxRequest(context.Request))
                            {

                            }

                            return Task.FromResult(0);
                        }
Coordinator
Dec 8, 2014 at 6:14 PM
You can provide this information when you issue the 401 if you use the Challenge API. There are two approaches:
  1. Set the authentication mode to Passive so it will only do redirects when it is directly challenged by auth type Challenge("WsFederation"). Passive WsFed will only react if invoked by auth type.
  2. Leave the authentication mode as Active and issue an alternate challenge when you want to bypass it Challenge("AJAX"). Active WsFed will only react if there are no auth types in the challenge Challenge() or if it is invoked by auth type.
Dec 8, 2014 at 6:35 PM
Thanks Tratcher,
Should I be setting the Challenge from inside a custom Authorize attribute somehow. At the moment the 401 is generated by the standard Authorize attribute.
I've found a way to set a challenge via getOwinContext but I can't seem to access this from inside an AuthorizeAttribute.
OR....
Is this similar to using the HostAuthenication attribute in a webapi controller? If so is there an equivalent in System.Web.MVC?
Coordinator
Dec 8, 2014 at 6:40 PM
Yes, several people have developed custom authorize attributes for this.

Here's one discussion:
http://stackoverflow.com/questions/20881461/authentication-and-authorizing-in-asp-net-mvc-5
Dec 8, 2014 at 7:23 PM
Thanks,
Before I started this thread I had created a Custom Authorize attribute and was setting the 401 status code there but it didn't seem to be working/I was still getting redirected. Although I still haven't worked out where to set the Challenge to "Ajax" I did stumble across filterContext.HttpContext.Response.End(); by looking at some of the custom authorize attributes as you suggested. So I've now ended up with the following that seems to be working as required. Do you see any issues with doing it this way or am I good to go?
public class AuthorizeNoLoginRedirectAttribute : System.Web.Mvc.AuthorizeAttribute
    {
        protected override void HandleUnauthorizedRequest(System.Web.Mvc.AuthorizationContext filterContext)
        {
            if (filterContext.HttpContext.Request.IsAjaxRequest())
            {
                filterContext.HttpContext.Response.StatusCode = 401;
                filterContext.HttpContext.Response.End();
            }
            base.HandleUnauthorizedRequest(filterContext); 
        }
    }
Many thanks for the help.
Coordinator
Dec 8, 2014 at 7:37 PM
No I don't recommend that. I think the extension you're looking for is filterContext.HttpContext.GetOwinContext().Authentication.Challenge("Ajax");
Dec 8, 2014 at 8:25 PM
Perfect, Works like a charm.
Thanks again for the help
public class AuthorizeNoLoginRedirectAttribute : AuthorizeAttribute
    {
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            if (filterContext.HttpContext.Request.IsAjaxRequest())
            {
                filterContext.HttpContext.GetOwinContext().Authentication.Challenge("Ajax");
            }
            base.HandleUnauthorizedRequest(filterContext);
        }
    }