C# OWIN API Valid access_token but NO User.Identity

We have an Angular 2+ SPA app using the auth0-js library (and angular2-jwt). It is configured properly and authenticating through Auth0 to a variety of identity providers successfully. By that I mean that we receive back a valid id_token and access_token which, looking through JWT.io, seem to have all of the correct values in place. We use the authHttp setup to call our own back-end C# API with the access_token. We can confirm that the access_token has the correct audience configured for that API.

SPA authHttp

export function authHttpServiceFactory(http: Http, options: RequestOptions) {
  return new AuthHttp(new AuthConfig({
    tokenName  : 'access_token',
    tokenGetter: (() => localStorage.getItem('access_token'))
  }), http, options);
}

C# API

var domain        = $"https://{ConfigurationManager.AppSettings"Auth0Domain"]}/";
var apiIdentifier = ConfigurationManager.AppSettings"Auth0ApiIdentifier"];
var keyResolver   = new OpenIdConnectSigningKeyResolver(domain);
app.UseJwtBearerAuthentication(new JwtBearerAuthenticationOptions {
    AuthenticationMode        = AuthenticationMode.Active,
    TokenValidationParameters = new TokenValidationParameters {
        ValidAudience            = apiIdentifier,
        ValidIssuer              = domain,
        IssuerSigningKeyResolver = (token, securityToken, identifier, parameters) =>
            keyResolver.GetSigningKey(identifier)
    }
});

Sometimes, some users will find that they can authenticate through the SPA fine (and thus Auth0 and the IDP) however our API calls fail with 403’s. Our API issues a 403 when we don’t receive a recognized user / token on the request. Using OWIN and the standard suggested Auth0 configuration, we can normally pull the User.Identity from within our API Controllers. In these circumstances, we get an empty / anonymous User.Identity.

Our assumption was that something was misconfigured / stale with the token and the OWIN JWT Auth0 process was legitimately rejecting the token as invalid and leaving the request as anonymous / unauthorized. We enabled OWIN detailed logging and went through some shenanigans to get that data logging from within Azure (where our API is being deployed). We had to do this because this only happens every once in a while and seems to strike at random. So we had to deploy and then wait until it happened again. Once it did happen, we were able to confirm that we see NO errors from OWIN at all. And this agrees with our own manual review of the token. The token has not expired. The signature is valid. The audience includes the API correctly (including slashes). Etc…

To be clear. When we are seeing this problem, ONE person is unable to login to ONE of our environments. Everyone else may be able to login to that environment fine and that person may be able to login to our other environments (some which share the same Auth0 domain). And, perhaps most strange, a restart of the API server is usually sufficient to allow that problem user (and likely all other users) to be able to login again. Until, randomly, the problem affects another user.

So somehow the token is valid, but something in the OWIN / JWT / Auth0 processing is failing to produce the User.Identity which is generated 99% of time for all users including the user who is, at that moment, unable to get authorized properly by the API.

We are now implementing our own JwtSecurityTokenHandler to inject additional debug logging and see if we can tell what is or isn’t happening when this problem hits us. It seems to strike at least one person at least once a day.

Anyone seen anything similar? What could the C# server be caching which eventually fails for a small subset of users but still work fine for all other users … and isn’t consistent between which users are affected? What “simple” issue are we overlooking?

I haven’t seen this issue before. An empty User (actually, an unauthenticated User.Identity) could also be generated by a missing token in the HTTP call (in which case the middleware simple does nothing, see https://katanaproject.codeplex.com/SourceControl/latest#src/Microsoft.Owin.Security.OAuth/OAuthBearerAuthenticationHandler.cs).
You can handle the RequestToken event in the Options.Provider to troubleshoot. This event is called with the token retrieved from the Authorization header, but it’s also called if no token is found. Logging this information might be useful.

We know (from the Dev Tools in the browser) that the correct and valid access_token JWT is present in the header. Additionally, that’s not something that is likely to change for a specific person at some random point in time. So it seems very unlikely that NO token is coming through. We’re waiting for a replication of the problem with our JwtSecurityTokenHandler logging. See if that gives us more information.

Still waiting …

We eventually tracked this down to an issue in our own systems. Apologies! It was a tough one to track down. Some kind of race condition ONLY when first spinning up our app.