-
Notifications
You must be signed in to change notification settings - Fork 351
experimental: Expose an OpenID Connect API #1019
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
Conversation
|
@pixlwave I haven't worked on the FFI bindings, will you handle that yourself? |
|
@zecakeh Yep, that’s totally fine by me, I’ll open another PR for the bindings when this gets merged 👍 Thanks for doing all the legwork on this 🙌 |
sandhose
left a comment
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.
I left a bunch of comments, but it looks good overall
A few things that I feel like I'm missing:
- how does the refresh token logic work? Can we make it transparent for the user?
- how transparent is it for an SDK user that it is an OIDC session?
- why is there both a builder-pattern struct to build an authorization request and one as a function with a bunch of parameters?
crates/matrix-sdk/src/oidc.rs
Outdated
| //! [`AuthenticateError::InsufficientScope`]: ruma::api::client::error::AuthenticateError | ||
| use chrono::Utc; | ||
| pub use mas_oidc_client::*; |
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.
Is that reexport right?
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.
I reduced it a bit but it's still not ideal, but it avoids to check which types need to be re-exported if we want users not to have to add the crate manually, like we do with Ruma.
The complicated part is that some types use a lot of other types (Verified)ProviderMetadata and (Verified)ClientMetadata among others, so we would have to hunt all the needed types.
It is however doable, if this is really not wanted.
crates/matrix-sdk/src/oidc.rs
Outdated
| pub(crate) fn new(client: Client) -> Self { | ||
| Self { client } | ||
| } |
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.
This feels a bit weird to me. Why would we need to carry the Matrix API client? Wouldn't it be enough to configure the OIDC client with issuer + HttpService, and have a method to get one from the Matrix API Client?
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.
OK, I guess it's for consistency with other 'modules' like that?
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.
We need to keep the OIDC data in memory, and until now users only had to keep the Client around so it felt like a simpler API to keep the data in memory inside the Client.
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.
Well, the Timeline API already deviates from this. I'm honestly not too happy with the ever-growing nature of Client. That said if it would be easy to misuse the API otherwise (which I think is not the case for the timeline), let's keep it as-is.
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.
If we want to make refreshing tokens transparent, we also need the Client to be able to use this API. Of course we could also make the client keep an Arc<OidcInner> and give an Oidc { inner: Arc<OidcInner>} or something like that.
crates/matrix-sdk/src/client/mod.rs
Outdated
| pub(crate) oidc_data: OnceCell<OidcData>, | ||
| /// The data needed to validate an OpenID Connect authorization request. | ||
| #[cfg(feature = "experimental-oidc")] | ||
| pub(crate) oidc_validation_data: Mutex<HashMap<String, AuthorizationValidationData>>, |
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.
It's probably OK for now, but it feels like it should be stored somewhere else, so that it can be serialized/stored and restored when it goes back to the client. For our use case it's probably fine, the Rust SDK will probably live through the whole flow
In OIDC clients for the browser, this kind of data is stored in the localstorage, and then the state parameter is there to support potentially multiple in-flight authorization, and restore associated parameters (in our case: homeserver, issuer, client registration infos)
|
We no longer depend on As the next step for this PR, can you please rebase? |
1a953db to
f4ec8ec
Compare
97071c1 to
5853ac3
Compare
Codecov ReportPatch coverage:
Additional details and impacted files@@ Coverage Diff @@
## main #1019 +/- ##
==========================================
- Coverage 77.97% 77.05% -0.93%
==========================================
Files 177 181 +4
Lines 18896 19130 +234
==========================================
+ Hits 14734 14740 +6
- Misses 4162 4390 +228
☔ View full report in Codecov by Sentry. |
…nnect Co-authored-by: Doug <[email protected]> Signed-off-by: Kévin Commaille <[email protected]>
Signed-off-by: Kévin Commaille <[email protected]>
Signed-off-by: Kévin Commaille <[email protected]>
Signed-off-by: Kévin Commaille <[email protected]>
Signed-off-by: Kévin Commaille <[email protected]>
Signed-off-by: Kévin Commaille <[email protected]>
|
All the TODOs were handled so it should be good for review again. |
| /// Set the requested Authentication Context Class Reference values. | ||
| /// | ||
| /// This is only necessary with specific providers. | ||
| pub fn acr_values(mut self, acr_values: HashSet<String>) -> Self { |
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.
If it's "Authentication Context Class Reference", why is the abbreviation acr instead of accr?
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.
I don't know, but that's the abbreviation used by OIDC. Also this is the exact name of the field this is supposed to fill.
Signed-off-by: Kévin Commaille <[email protected]>
This is a WIP implementation of OpenID Connect authentication using matrix-org/matrix-authentication-service#347.
I tried to write a thorough documentation in the
oidcmodule on how to use it/what it supports.This has been successfully tested against the
synapse-oidc.lab.element.devserver from the OIDC Playground using the example CLI inexamples/oidc-cli(logging and syncing). There is one quirk though, automatic refresh of token doesn't work because we don't seem to get the proper error type from Synapse.It is currently not compatible with the
synapse-auth0-oidc.lab.element.devbecause of a metadata deserialization issue, and hasn't been tested with the 2 others because they don't have open registration according to the table.Related to #859