Identity Server 3 - 401 on Ajax Calls instead of 302

asp.net, asp.net-mvc-5, cookies, identityserver3

Solution

In your example the `UseCookieAuthentication` no longer controls this, instead the `UseOpenIdConnectAuthentication` does. This involves using the `Notifications` property and intercepting OpenID Connect authentication requests.

Try out the following for inspiration:

app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
    Authority = IdentityConfig.Authority,
    ClientId = IdentityConfig.SoftwareClientId,
    Scope = "openid profile roles",
    RedirectUri = IdentityConfig.RedirectUri,
    ResponseType = "id_token",
    SignInAsAuthenticationType = "Cookies",
    Notifications = new OpenIdConnectAuthenticationNotifications
    {
        RedirectToIdentityProvider = notification =>
        {
            if (notification.ProtocolMessage.RequestType == OpenIdConnectRequestType.AuthenticationRequest)
            {
                if (IsAjaxRequest(notification.Request) && notification.Response.StatusCode == (int)HttpStatusCode.Unauthorized)
                {
                    notification.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                    notification.HandleResponse();
                    return Task.FromResult(0);
                }
            }
            return Task.FromResult(0);
        }
    }
});

Problem

I have a web api / mvc hybrid app and I have configured it to use cookie authentication. This works fine for the mvc portion of the application. The web api does enforce the authorization, but instead of returning a `401 - Unauthorised` it returns a `302 - Found` and redirects to the login page. I would rather it returns a `401`. I have attempted to hook into the `CookieAuthenticationProvider.OnApplyRedirect` delegate, but this doesn't seem to be called. What have I missed? My current setup is below: ``` AntiForgeryConfig.UniqueClaimTypeIdentifier = Constants.ClaimTypes.Subject; JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string, string>(); app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = "Cookies", ExpireTimeSpan = TimeSpan.FromMinutes(20), SlidingExpiration = true, CookieHttpOnly = true, CookieSecure = CookieSecureOption.Never, //local non ssl-dev only Provider = new CookieAuthenticationProvider { OnApplyRedirect = ctx => { if (!IsAjaxRequest(ctx.Request)) { ctx.Response.Redirect(ctx.RedirectUri); } } } }); app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions { Authority = IdentityConfig.Authority, ClientId = IdentityConfig.SoftwareClientId, Scope = "openid profile roles", RedirectUri = IdentityConfig.RedirectUri, ResponseType = "id_token", SignInAsAuthenticationType = "Cookies" }); ```

Original source