Client/auth-code-flow: Handle multiple interfaces w/ hostname localhost#10818
Draft
snazy wants to merge 3 commits intoprojectnessie:mainfrom
Draft
Client/auth-code-flow: Handle multiple interfaces w/ hostname localhost#10818snazy wants to merge 3 commits intoprojectnessie:mainfrom
localhost#10818snazy wants to merge 3 commits intoprojectnessie:mainfrom
Conversation
…ost` Auth-code-flow test recently started to fail in CI for all PRs. Difficult to tell which change really causes the issues here. Background: `org.projectnessie.client.auth.oauth2.AuthorizationCodeFlow` binds to the inet-address returned by `InetAddress.getLoopbackAddress()` and the redirect-URL uses `localhost`. "As usual", the affected test `ITOAuth2ClientAuthelia` works fine locally. However, there's a little difference in the environment. In GH workflows, `localhost` resolves to both ::1 and 127.0.0.1, whereas locally `localhost` only resolves to 127.0.0.1. So it feels related to IPv4 vs IPv6. Some experiments with different contents in `/etc/hosts`: ``` ::1 localhost 127.0.0.1 localhost ``` --> test passes ``` 127.0.0.1 localhost ::1 localhost ``` --> test passes ``` 127.0.0.1 localhost ``` --> test passes ``` ::1 localhost ``` --> test fails This means that the issue is defintely related to which IP address (`127.0.0.1` or `::1`) `localhost` resolves to. The change in this PR is to start one HTTP server for all loopback IP addresses. Alternatives were: * Bind to "all addresses": this feels a bit insecure, because it would open the http server to remote requests * Inspect which interfaces have `localhost` in `InetAddress.getHostName()`. This performs a roundtrip to at least the local resolver, but more importantly it can still yield multiple addresses. * Resolve `localhost` via `InetAddress.get[All]ByName()`. This performs a name service roundtrip (_usually_ only the local resolver, but still) - but it can also yield multiple addresses. * Use the IP address (`127.0.0.1` or `::1` or whatever host address `InetAddress.getLoopbackAddress().getHostAddress()` returns) in the redirect URL. This would require changes to the allowed redirect-URLs in Authelia/Keycloak configurations. On top, some implementations have issues parsing IPv6 addresses in URLs (e.g. `http://[::1]:54321/foo/bar`) due to the repeated `:`. * Inspect `/etc/hosts` - it's another can of worms especially on all the different operating system. So getting into that area for this use case feels wrong. Side note: the order in which resolvers return an IP address is up to the resolver. There are no guarantees from a client's side of view (beside that some IP address, if resolvable, is returned). Overall the approach to listen to all loopback addresses seems to be the best approach. Additional debug logging has been added.
1 task
Member
Author
|
Meh - even this approach didn't help :( |
f210064 to
32e5139
Compare
32e5139 to
067e59e
Compare
Member
Author
|
Aha! The assertion-error was never exposed. |
Member
Author
|
Looks like it's an issue w/ Authelia and the requested But this doesn't really explain why the test passes locally but not in GHA. |
75be204 to
52d3343
Compare
Member
Author
|
Maybe @adutra has an idea here. I'm a bit lost. |
snazy
added a commit
to snazy/nessie
that referenced
this pull request
May 16, 2025
See also projectnessie#10818, especially this comment: Looks like it's an issue w/ Authelia and the requested `offline_access` scope, because of [`If the client requests the offline_access or offline scope the mode will automatically be explicit regardless of client configuration.`](https://www.authelia.com/configuration/identity-providers/openid-connect/clients/#implicit). But this doesn't really explain why the test passes locally but not in GHA.
snazy
added a commit
that referenced
this pull request
May 16, 2025
See also #10818, especially this comment: Looks like it's an issue w/ Authelia and the requested `offline_access` scope, because of [`If the client requests the offline_access or offline scope the mode will automatically be explicit regardless of client configuration.`](https://www.authelia.com/configuration/identity-providers/openid-connect/clients/#implicit). But this doesn't really explain why the test passes locally but not in GHA.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Auth-code-flow test recently started to fail in CI for all PRs. Difficult to tell which change really causes the issues here.
Background:
org.projectnessie.client.auth.oauth2.AuthorizationCodeFlowbinds to the inet-address returned byInetAddress.getLoopbackAddress()and the redirect-URL useslocalhost."As usual", the affected test
ITOAuth2ClientAutheliaworks fine locally. However, there's a little difference in the environment. In GH workflows,localhostresolves to both ::1 and 127.0.0.1, whereas locallylocalhostonly resolves to 127.0.0.1. So it feels related to IPv4 vs IPv6.Some experiments with different contents in
/etc/hosts:--> test passes
--> test passes
--> test passes
--> test fails
This means that the issue is defintely related to which IP address (
127.0.0.1or::1)localhostresolves to.The change in this PR is to start one HTTP server for all loopback IP addresses.
Alternatives were:
localhostinInetAddress.getHostName(). This performs a roundtrip to at least the local resolver, but more importantly it can still yield multiple addresses.localhostviaInetAddress.get[All]ByName(). This performs a name service roundtrip (usually only the local resolver, but still) - but it can also yield multiple addresses.127.0.0.1or::1or whatever host addressInetAddress.getLoopbackAddress().getHostAddress()returns) in the redirect URL. This would require changes to the allowed redirect-URLs in Authelia/Keycloak configurations. On top, some implementations have issues parsing IPv6 addresses in URLs (e.g.http://[::1]:54321/foo/bar) due to the repeated:./etc/hosts- it's another can of worms especially on all the different operating system. So getting into that area for this use case feels wrong.Side note: the order in which resolvers return an IP address is up to the resolver. There are no guarantees from a client's side of view (beside that some IP address, if resolvable, is returned).
Overall the approach to listen to all loopback addresses seems to be the best approach.
Additional debug logging has been added.