aspnet / AspNetKatana

Microsoft's OWIN implementation, the Katana project
Apache License 2.0
967 stars 334 forks source link

OnValidateIdentity in OWIN Cookie authentication middleware not called #144

Closed peter-bannerflow closed 6 years ago

peter-bannerflow commented 6 years ago

I am using the OWIN cookie authentication middleware and have setup a custom OnValidateIdentity-method that should be invoked on all requests that needs to be authenticated.

My setup looks like this:

        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = "my-cookie",
            Provider = new CookieAuthenticationProvider()
            {
                OnValidateIdentity = async ctx =>
                {
                    // my own validation code
                }
            }
        }

The issue I have is that for some requests, OnValidateIdentity is not called. If I hit the same protected Web API controller multiple times, some of the requests would not invoke the OnValidateIdentity-method.

This leads to issues later in the processing when I need to use GetOwinContext().Authentication.User and the ClaimsPrincipal is not populated.

What could be the reason for this?

Tratcher commented 6 years ago

It sounds like those requests did not have an auth cookie, or at least not a valid one. It must pass all of the built in validation before the OnValidateIdentity event is called. CookieAuth does not reject anonymous requests, that's what [Authorize] is for.

Start by taking a Fiddler trace to see what's different about those requests.

peter-bannerflow commented 6 years ago

I've checked that the request does have a cookie matching the name specified by the AuthenticationType-property. Wether it is valid or not is harder to say since the data inside it is protected.

I've looked into whats going on in AuthenticateCoreAsync (https://github.com/aspnet/AspNetKatana/blob/dev/src/Microsoft.Owin.Security.Cookies/CookieAuthenticationHandler.cs#L39) and from what I can see, the things that could cause the middleware to not call my method are:

  1. Cookie not being set
  2. Creating the AuthenticationTicket fails
  3. Session store being used without the SessionId claim set
  4. Expire time passed

So I have confirmed that case 1 is not an issue. Not sure about case 2, is there any way I can validate this?

Case 3 should not be an issue since I am not using the session store. Case 4 should also not be an issue since I use the default expire timespan.

Tratcher commented 6 years ago

You can check the app logs. most of those failures are logged. https://github.com/aspnet/AspNetKatana/wiki/Debugging

peter-bannerflow commented 6 years ago

Found the issue. The cookie was expired.

This is because I also use the OpenIdConnect-middleware using the same cookie. Turns out that if you don't specify UseTokenLifetime = false in that config, it will use the expiry of the ID token as cookie expiry. So the problem I saw was in fact due to the cookie being expired, so just as you said it didn't pass all the built in validation.

Thanks for the help!