skoruba / IdentityServer4.Admin

The administration for the IdentityServer4 and Asp.Net Core Identity
MIT License
3.57k stars 1.15k forks source link

Correlation failed, when Admin is hosted behind a reverse proxy server under a directory #888

Closed Foxite closed 3 years ago

Foxite commented 3 years ago

I have my own, custom SSO service running together with the admin frontend/api projects for easy administration.

During development, I would use a docker-compose file mostly identical to the one in this repository. The SSO container would use "sso.service.local" as the url, admin would use "admin.skoruba.local" and admin.api would use "admin-api.skoruba.local". Everything worked perfectly that way.

Now it's time to go live, and instead of the nginx proxy from docker-compose.yml, we use our existing Apache2 server to act as the reverse-proxy server. Now, the url for SSO is "id.company.com", and here's the part I think is important: the urls for admin and admin.api are "admin.company.com/identity" and "admin.company.com/identity-api".

In this scenario, our SSO system appears to function normally, including the apps we used to test our SSO service during development. However, when we try to log in to admin.company.com/identity, when the browser makes the call to admin.company.com/identity/signin-oidc, this error is produced:


Exception: Correlation failed.

Exception: An error was encountered while handling the remote login.

    Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler<TOptions>.HandleRequestAsync()
    Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
    Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context)
    NWebsec.AspNetCore.Middleware.Middleware.CspMiddleware.Invoke(HttpContext context)
    NWebsec.AspNetCore.Middleware.Middleware.MiddlewareBase.Invoke(HttpContext context)
    NWebsec.AspNetCore.Middleware.Middleware.MiddlewareBase.Invoke(HttpContext context)
    NWebsec.AspNetCore.Middleware.Middleware.MiddlewareBase.Invoke(HttpContext context)
    NWebsec.AspNetCore.Middleware.Middleware.MiddlewareBase.Invoke(HttpContext context)
    Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

Because of the reverse proxy server being configured approximately like this:

ServerName admin.company.com
ProxyPass /identity https://server:5000

The URL seen by the admin container is this: https://admin.company.com/signin-oidc when the browser believes it to be https://admin.company.com/identity/signin-oidc. This discrepancy, I believe, is the reason for the exception.

Another symptom of this problem is that the cookie stored by the browser is for the domain "admin.company.com", and the path is "/signin-oidc" rather than "/identity/signin-oidc" as the path is determined by the server rather than the browser, and the server determines the path based on what the client sends it. The client in this case is the reverse proxy server which modifies the path so it does not include /identity.

The solution should be to make the admin system aware of the base url. How do I do this?

Alternatively, if I'm entirely wrong: how do I fix the exception?

Foxite commented 3 years ago

The solution to this problem is to write a middleware that sets the PathBase of any HTTP request to "/identity". Make sure that the proxy server does not include "/identity" in its target url. (ProxyPass /identity https://server:5000)

Also do the same for Admin.Api, but with /identity-api of course.