-
Notifications
You must be signed in to change notification settings - Fork 21
v6: Support OIDC authentication #438
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
Open
bevzzz
wants to merge
28
commits into
v6
Choose a base branch
from
v6-oidc
base: v6
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Conversation
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Orca Security Scan Summary
Status | Check | Issues by priority | |
---|---|---|---|
![]() |
Secrets | ![]() ![]() ![]() ![]() |
View in Orca |
This is a large chagne that requester modifying some internals: - Extended Endpoint interface with requesturl overload that takes RestTransportOptions and builds a full request URL instead of leaving it up to DefaultRestTrasport - Added ExternalEndpoint that allows sending REST requests to arbitrary URIs. - Added a thin wrapper around Nimbus OAuth2 SDK to refresh tokens. - Made Authorization an interface that can getTokenProvider().
Since HTTP client can use a thread pool executor, token provider is likely to be accessed concurrently. We only allow 1 thread at a time working with the token
Added isLive to both sync/async client to ping the server
A custom HttpResponseParser handles the non-compliant error response format that some OIDC servers (e.g. Okta) return. Refactored ResourceOwnerPassword flow to exchange the grant for the access_token once and then switch to RefreshToken flow.
Document public and internal APIs.
redirect_uri is set in the old Java client but it's nowhere to be found Python and TS clients. Also tests show that it's not required for exchanging tokens
Deleted NimbusTokenProvider.BearerTokenFlow class, no longer used. Added a wrapper for WeaviateClient that can tie client's lifetime to that of the Testcontainer that created it. That way the client, once opened, is only closed when the container it belonged to is stopped.
Refreshing the token slightly ahead of its expiry can help prevent phony unauthorized access errors.
Add another interface method to AsyncTokenProvider to schedule the future on a custom executor.
It is possible for a refresh_token to expire after a long period of inactivity depending on the IdP. This ensures that a new token is fetched at least once after the access_token expires.
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.
What's changed
This PR adds support for the three OIDC authentication flows supported in other clients.
Bearer Token
An existing access_token + refresh_token pair can be readily used.
Resource Owner Password
If no scopes are provided, Resource Owner Password request is sent with
"offline_access"
scope.After exchanging the password for an access-/refresh-token pair, then client will switch to Bearer Token flow.
Client Credentials
If no scopes are provided and we're authenticating against a Microsoft IdP, Client Credentials request is sent with
client_id + "./default"
scope.Internals
The implementation is heavily inspired by Golang's
oauth2
package, both the public API and internals.At the root of it is the
TokenProvider
interface (TokenSource in Go-speak), which has one simple methodToken getToken()
. Theio.weaviate.internal.oidc.nimbus
package provides implementation for each of the supported OIDC flows, such that switching to another dependency should be rather easy (if ever necessary).ReuseTokenProvider caches the token for as long as it remains valid and then fetches a new one using some other TokenProvider it wraps around.
Similarly, ExchangeTokenProvider takes a single-use TokenProvider to obtain a token pair in exchange for a grant (e.g. Resource Owner Password) and then creates a ReuseTokenProvider to refresh the access token continuously.
AsyncTokenProvider supports fetching tokens asynchronously as
CompletableFuture<Token>
, so that our AsyncClient does not have blocking calls in the chain. I extendedrest.AuthenticationInterceptor
to handle async requests differently. Its gRPC-twin, TokenClientCredentials, only needed a minimal change to accommodate this.All tokens are configured with a 30s
expiryDelta
, which forces the client to refresh a token before it actually expires. This should prevent unauthorized access errors caused by poor timing.Closes #421