-
Notifications
You must be signed in to change notification settings - Fork 163
Client/auth-code-flow: Handle multiple interfaces w/ hostname localhost
#10818
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
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.
|
Meh - even this approach didn't help :( |
f210064 to
32e5139
Compare
32e5139 to
067e59e
Compare
|
Aha! The assertion-error was never exposed. |
|
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
|
Maybe @adutra has an idea here. I'm a bit lost. |
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.
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.
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.