Environment:
- IdentityServer4 instance supporting implicit flow
- Angular 7 client apps using oidc-client-js
- ASP.NET Framework Web API resources using the IdentityServer3 Katana Access Token Validation Middleware
Basic token issuance and validation is working fine in our environment. I am now trying to enable the silent refresh technique (as documented here). After enabling automaticSilentRenew
and a short AccessTokenLifetime
, I can see the silent requests firing off in my browser console as I would expect.
I can see two subsequent calls to the UserInfo endpoint of IS4 (see screenshot below). The first is the CORS preflight OPTIONS
request. At a breakpoint in my custom implementation of IProfileService.IsActiveAsync()
, I can see that this request successfully authenticates (by inspecting httpContext
).
public class ProfileService : IProfileService
{
private readonly HttpContext _httpContext;
public ProfileService(IHttpContextAccessor httpContextAccessor)
{
_httpContext = httpContextAccessor.HttpContext;
}
...
public async Task IsActiveAsync(IsActiveContext context)
{
var temp = _httpContext.User; // breakpoint here
// call external API with _httpContext.User info to get isActive
}
}
However, the second request (GET
) to the UserInfo endpoint does not authenticate. My breakpoint in IProfileService.IsActiveAsync()
shows no user authenticated, so my routine for verifying if the user is active (calling out to another API) returns false which is translated to a 401. I can see this header on the failing GET
request WWW-Authenticate: error="invalid_token"
.
I have tried specifying an IdentityTokenLifetime
that is less than the AccessTokenLifetime
per this with no success.
Here are the logs of the two requests:
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 OPTIONS http://localhost:5000/connect/userinfo
Microsoft.AspNetCore.Cors.Infrastructure.CorsService:Information: CORS policy execution successful.
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 8.5635ms 204
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:5000/connect/userinfo
Microsoft.AspNetCore.Cors.Infrastructure.CorsService:Information: CORS policy execution successful.
Microsoft.AspNetCore.Cors.Infrastructure.CorsService:Information: CORS policy execution successful.
IdentityServer4.Hosting.IdentityServerMiddleware:Information: Invoking IdentityServer endpoint: IdentityServer4.Endpoints.UserInfoEndpoint for /connect/userinfo
IdentityServer4.Validation.TokenValidator:Error: User marked as not active: f84db3aa-57b8-48e4-9b59-6deee3d288ad
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 94.7189ms 401
Question:
How can I get the GET
request to the UserInfo endpoint during the silent refresh to authenticate into HttpContext
?
Update:
Adding screenshots of all of the headers of the two requests and the resulting browser cookies to investigate the answer by @Anders.