spring-authorization-server: Issuer should not support path component

The issuer setting, if supplied via AuthorizationServerSettings.getIssuer(), should not support a path component.

With the current and all previous versions, if AuthorizationServerSettings.getIssuer() was explicitly set with https://provider.com/issuer1, the protocol endpoint URI’s returned by OidcProviderConfigurationEndpointFilter and OAuth2AuthorizationServerMetadataEndpointFilter would all be incorrect. For example, token_endpoint would be https://provider.com/issuer1/oauth2/token, which would not resolve for the client since the token endpoint matches on /oauth2/token (by default) and not /issuer1/oauth2/token.

This fix should add a validation preventing a path component for issuer.

NOTE: The path component enables supporting multiple issuers per host for multi-tenant configurations. This enhancement request is being tracked in gh-1342.

Related gh-1419 gh-1416

About this issue

  • Original URL
  • State: closed
  • Created 8 months ago
  • Comments: 18

Commits related to this issue

Most upvoted comments

@rd-marc-lehnert, @jonkjenn, @tkrah, @Prigovor

Apologies for the issue this update has caused. I did not account for Proxy related settings. I went ahead and reverted this update across all branches.

Hello @jgrandja, we just tried to upgrade our authorization server which is behind a proxy under a different path with the issuer: https://server.domain/auth and a reverse proxy pointing https://server.domain/auth to http://backend-service. This setup now no longer works because the server does not start (Path component for issuer (...) is currently not supported). This prevents us from upgrading to Version 1.2.

@rd-marc-lehnert @jonkjenn I’m not sure how you were even able to get it working with a path component? As mentioned in the main issue:

With the current and all previous versions, if AuthorizationServerSettings.getIssuer() was explicitly set with https://provider.com/issuer1, the protocol endpoint URI’s returned by OidcProviderConfigurationEndpointFilter and OAuth2AuthorizationServerMetadataEndpointFilter would all be incorrect. For example, token_endpoint would be https://provider.com/issuer1/oauth2/token, which would not resolve for the client since the token endpoint matches on /oauth2/token (by default) and not /issuer1/oauth2/token.

If you apply the patch issuer-path.patch to main, you will see that the default-authorizationserver sample does not work. Try accessing http://localhost:9000/auth/.well-known/openid-configuration and you will get a 404.

issuer-path.patch

However, if you require a path component in your current setup, then you can configure server.servlet.context-path to achieve the same. If you apply the patch context-path.patch to main, you will be able to access http://localhost:9000/auth/.well-known/openid-configuration and the issuer identifier will dynamically resolve to http://localhost:9000/auth.

context-path.patch

Hope this helps?

@jgrandja Thank you so much for the revert! We ran into this problem today as well. I just wrote a huge bugreport explaining why the proposed solution with context-path will not work for us. But before I hit “submit”, I saw your latest reply. Very glad 😃

My authorization server also behind proxy, upgrade and hit the same issue. With help in this thread, and another one https://github.com/spring-projects/spring-security/issues/5631, I got it running. Here is what I did, FYI:

  • remove issuer configuration in AuthorizationServerSettings as advised above
  • put server.forward-headers-strategy=FRAMEWORK to my Authorization server. Without this one, auto-generated issuer URI will be http instead of https behind proxy

Looking forward to get configure issuer URI capability back. Thanks.

@Prigovor Just by making sure that whatever path we had publicly e.g. https://example.com/some-path/auth is the same path as the application has internally e.g. http://some-application:1234/some-path/auth so that you can take the path segment some-path/auth and apply it via server.servlet.context-path instead. I don’t know how you would handle situations where you cannot have the same path.

Yes then our /.well-known/openid-configuration ends up correct with a combination of protocol and domain from the request, the context path and the settings from AuthorizationServerSettings.builder().authorizationEndpoint("/oauth2/auth").... We let issuer be configured automatically. (Except for our trailing slash issue.)

@tkrah Since you’re setting server.servlet.context-path, you should not set AuthorizationServerSettings.getIssuer()

I have to, the external url is not the same like the one from the host which is running the auth server, so I need to set that issuer URI to get correct URLs and I need the context path to map it from the proxy from proxy X -> destination Y and using:

server.forward-headers-strategy: framework

I did configure both, the AuthorizationServerSettings.getIssuer() (including the context path)

The AuthorizationServerSettings.getIssuer() with a path component will not resolve. Please see this comment for details.

I just use 1.1.3 and I can tell you it does resolve that path component, the token endpoint is reachable with configured context path and issuer with context path, it works here without a problem.

To solve this, simply remove the AuthorizationServerSettings.getIssuer() setting and preserve server.servlet.context-path and it should work.

That does not work because I need a custom issuer URI - which all works in 1.1.3 😉

@jgrandja

I’m not sure how you were even able to get it working with a path component? Main reason might be that we used Customizer<OidcProviderConfigurationEndpointConfigurer> to rewrite some paths.

We did manage to upgrade now though by running the same path internally as externally.

One remaining issue with the new issuer limitation though is handling an issuer with a trailing slash. I know it’s horrible but it’s not easy to move away from. So for us it would still be nice to be able to hard code the complete issuer.

I did configure both, the AuthorizationServerSettings.getIssuer() (including the context path) and the server.servlet.context-path and it works with 1.1.3. Trying to switch to 1.2.0 that setup breaks now.