Closed promim closed 2 months ago
For container deployments, the default ASP.NET Core port changed from 80 to 8080. It looks like this is the cause of your problem. It might require configuration updates to either continue using port 80 or to migrate to using 8080.
@RolandGuijt I've downgraded both apps (the IdentityServer implementation oauth
to .NET 6 and IdentityServer 6.3; the MVC/OIDC client devframe
to .NET 6) and the issue is still there. The port breaking change was introduced in .NET 8.
EDIT: Added additional info about how devframe
and oauth
are configured to start up if that helps explain the setup.
I've reviewed the details you shared once more and this is indeed not caused by the Asp.Net Core default port changes. Those are a very common issue for docker based deployments so that is our first check for any issues when hosting .NET 8 on Docker.
It looks like you have a DNS/host name oauth
setup for your IdentityServer. But when IdentityServer processes the request it does not see/accept that host name. I would suggest that you focus on getting the discovery document right. If you access it on https://oauth/.well-known/openid-configuration
all the URLs in the discovery document should be to https://oauth/...
too. Does your Docker setup include a virtual reverse proxy? Is that configured correctly to emit forwarded headers? Is your IdentityServer host configured correctly to accept forwarded headers? Please see our docs on deployment with proxies for more information on that setup.
If everything is working correctly, IdentityServer should emot URLs (including the JWKs URL) that are under the same host name as the request, e.g. `https://oauth/.well-known/openid-configuration/jwks".
@AndersAbel Thanks for the reply.
We do not have a virtual reverse proxy, and never assumed it would be necessary. Especially since the setup was working fine on IdentityServer4.
I was just able to override the endpoints that I receive from the discovery document with the following setup on the MVC client (dev-frame
).
builder
.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
options.Configuration = new OpenIdConnectConfiguration
{
JwksUri = "https://oauth/.well-known/openid-configuration/jwks",
TokenEndpoint = "https://oauth/connect/token"
};
// ...
It looks like this is only necessary for the endpoints that are called via back-channel (so far I only figured it's the JWKs and the Token endpoints). Is there a better way to do this? Or perhaps a list of endpoints that are called via back-channel by Microsoft's OIDC middleware?
That code would fix the immediate problem, but still doesn't address the root cause, that IdentityServer does not recognize the right host name on the requests. I would recommend getting the host name resolution through IServerUrls
correct as that fixes the issue for real. Changing the configuration on the client side is of more a work-around.
@AndersAbel That causes other issues that got me worried about other stuff breaking. For example, IdentityServer redirecting to a custom login URL that was set up in the IdentityServer configuration:
services
.AddIdentityServer(options =>
{
options.UserInteraction.LoginUrl = "/custom-login-url";
// ...
would end up with https://oauth/custom-login-url in the browser, which would never be resolved.
Oh, it looks like this is getting more complicated now. So the oauth
address is really not the address that users' browsers will see/show? Having IdentityServer listen/work on different addresses internally and externally is usually a bad idea. The base address is used as the issuer
in tokens to identify the OAuth2/OIDC Authority. If different clients/browsers/APIs see different values for that they might reject tokens.
I would recommend making sure that all clients/APIs and users access the IdentityServer using the same host name. If you want docker internal traffic to be possible, I would recommend using split DNS or hosts files to override the public IP address resolution.
So the
oauth
address is really not the address that users' browsers will see/show?
That won't be possible, as "https://oauth" is only supposed to be called by a containerized app such as the MVC client here or an API. As far as IdentityServer is concerned, it receives requests already translated to "localhost:6501". In the browser, the IdentityServer is always called with "localhost:6501".
I still don't understand why this setup was working in IdentityServer4 and not as soon as IServerUrls was introduced. The MVC client always saw the JWKs and the Token endpoints as they were presented in the discovery document (with a localhost:6501
host).
Would it be possible for you to present an example with IdentityServer, an MVC client and an API, each running in a separate Docker container?
This must be a development environment then? Because I guess you do not have IdentityServer actually answering on localhost
in production?
When running containerized I've found that it is hard to keep using localhost
for interaction with the local environment. A DNS/host name alias is often needed. I think that if you setup a specific host name that can be used both by the users' browsers and the API/client within the containers it should start working.
Yes, this is a development environment setup. It would still help a lot if you provided a sample with the mentioned setup. I think it would help a lot of developers struggling with such containerized development configuration.
Our default development setup is to run everything on localhost directly, without containers. It's perfectly possible to set up IdentityServer in a containerized deployment. There are many different ways to do that and there is no solution that fits everyone. Any implementation of IdentityServer needs to make decisions on how to deploy the solution. If opting for containers, virtual networks or anything similar it requires considering the consequences and setting up a proper name resolution. For example, most deployments I've seen in the past uses a reverse proxy and you are not. Either way is fine, I just want to point out that all deployments are different. It would unfortunately not be possible for us to setup and maintain containerized deployment examples that cover the relevant scenarios.
The only generic advice I can give is that the DNS name of the IdentityServer is a fundamental part of the security model. All clients, APIs and user devices should use the same DNS name to communicate with IdentityServer.
Thanks for the assistance nevertheless. We decided to go with this for now for the development setup where we disable issuer validation as well, until we figure out a way to use some sort of a reverse proxy to align the use of the same DNS name that's not localhost.
builder .AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options => { options.Configuration = new OpenIdConnectConfiguration { JwksUri = "https://oauth/.well-known/openid-configuration/jwks", TokenEndpoint = "https://oauth/connect/token" }; // ...
We can close this.
Which version of Duende IdentityServer are you using? 7.0.4
Which version of .NET are you using? 8.0.3
Describe the bug We've just migrated our IdentityServer4 implementation to Duende IdentityServer v6 and v7 subsequently. We have had a development setup, where we run the IdentityServer implementation in a Docker container and an MVC client application (with configured OIDC) in another Docker container. It appears that after the required IServerUrls change in one of the Duende IdentityServer v6 subversions, this setup no longer works as before.
To Reproduce
Steps to reproduce the behavior.
The IdentityServer implementation (referred to as
oauth
) is available at https://localhost:6501 (which is also the IServerUrls.Origin implementation) The MVC client application (referred to asdevframe
) is available at https://localhost:31111docker-compose looks like this
After accessing
devframe
at https://localhost:31111 in the browser, we trigger an action that challenges the OIDC authentication scheme. Since the authority in the OIDC configuration is set to OAUTH_AUTHORITY (https://oauth), we are able to hit the discovery document endpoint, but since the JWKS URI is set to localhost:6501,devframe
from within its container is not able to access it.A clear and concise description of what you expected to happen.
Something around the time when the IServerUrls change was introduced seems to have caused this problem.
Log output/exception with stacktrace
Additional context
Notice that the communication between the containers seems fine, I can ping any endpoint on
oauth
from within thedevframe
container terminal:Not sure if relevant, but when running the server and the client, I do get the following logs on both
devframe
andoauth
:Both
devframe
andoauth
are configured to start up with the following setup: