-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Support OidcProviderClient injection and token revocation #44993
base: main
Are you sure you want to change the base?
Conversation
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 looks good, but my understanding was that you want to move towards unification of the io.quarkus.oidc.client.runtime.OidcClientImpl
and io.quarkus.oidc.runtime.OidcProviderClient
as part of the #39298. Wouldn't it be smarter to define some common API shared by both clients that you will expose? Otherwise when that happens, you will need to take into considerations users may already sue the OidcProviderClient
when making changes.
🎊 PR Preview e4cab19 has been successfully built and deployed to https://quarkus-pr-main-44993-preview.surge.sh/version/main/guides/
|
I didn't realise we have two client classes. Good point about this being confusing. Also, this PR doesn't have any docs, which is what I'm most interested in :-/ |
Hi @FroMage, What @michalvavrik pointed out is indeed a target, expand the scope of what Michal, I actually started thinking about it during the
So, as far as So, to summarize, right now, I'm not certain at all a shared interface idea is worth it given that probably the only missing piece in |
...n-tests/oidc-wiremock-logout/src/main/java/io/quarkus/it/keycloak/SecurityEventListener.java
Show resolved
Hide resolved
Got it @sberyozkin , I had a look again and I think this is useful. I suppose you will add docs when you make this ready for a review, so just one question:
|
Sure, this is what I was thinking about as well, in the description with I've been thinking quite a lot during the last week about how to share interfaces between I may be repeating it, but I guess trying to come up with a shared interface to support these 2 extensions whose user audiences and goals are different may not be particularly useful and be rather constraining. I think what we can definitely try to do is to minimize duplication between As far as what After this PR is reviewed and approved, I can try to do #39298 by going after introducing shared |
19529a2
to
8990d81
Compare
@michalvavrik Hi Michal, so I've introduced
What are your thoughts about it ? I plan to add some docs next. |
8990d81
to
983a9f9
Compare
I've added initial docs. I'm not really focusing there on |
I'll read all tomorrow evening @sberyozkin , quite busy on finishing other PR ATM. |
983a9f9
to
ad479c3
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
ad479c3
to
250d1d1
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
250d1d1
to
93ac981
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
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.
Looks very good!
docs/src/main/asciidoc/security-oidc-code-flow-authentication.adoc
Outdated
Show resolved
Hide resolved
Sometimes, you may want to revoke the current authorization code flow access and/or refresh tokens. | ||
For example, if the user has logged out, your logout event listener can revoke access refresh tokens associated with the currenty session. | ||
|
||
`quarkus.oidc.OidcProviderClient` which provides access to the OIDC provider's UserInfo, token introspection and revocation endpoints, can be used to support such cases. |
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 reads bit strange to me to start with code quarkus.oidc.OidcProviderClient
. Not sure if The
belongs there, but let see if anyone else things it reads strange too. If not, it's OK.
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.
@michalvavrik Yeah, I'm not sure either :-), let me change this sentence slightly and drop the package name as it will be shown in the example below
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.
@michalvavrik I've kept the package name but restructured a bit, from what I've seen, omitting the
seems acceptable when referring to (Java) class names, but it can be easily tuned if needed
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.
Thanks, read well now.
1cb4b2c
to
849bbb2
Compare
@michalvavrik Thanks for the review. I've found it a bit tricky to expose some of these methods cleanly. Currently On So, in this PR I pushed some of |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
849bbb2
to
8874a06
Compare
Status for workflow
|
Status for workflow
|
@FroMage Have a look please next week if you can at the docs and comments clarifying some design decisions, I believe with this PR you can have an Apple logout and token revocation issue resolved quite neatly. In general, I'm thinking it will be hard to create a uniform client interface between Going forward I may be able to reuse some beans like |
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.
Added comments and questions about the API and docs, but I haven't checked the impl code.
Sometimes, you may want to revoke the current authorization code flow access and/or refresh tokens. | ||
For example, if the user has logged out, your logout event listener can revoke access refresh tokens associated with the current session. | ||
|
||
To support such cases, you can use `quarkus.oidc.OidcProviderClient` which provides access to the OIDC provider's UserInfo, token introspection and revocation endpoints. |
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.
Are you sure there's a use-case for revoking tokens after a back-channel logout? Aren't the tokens automatically revoked by the OIDC server?
|
||
public void event(@ObservesAsync SecurityEvent event) { | ||
if (SecurityEvent.Type.OIDC_BACKCHANNEL_LOGOUT_COMPLETED == event.getEventType()) { <1> | ||
OidcProviderClient oidcProvider = event.getSecurityIdentity().getAttribute(OidcProviderClient.class.getName()); <2> |
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.
What's the rationale for obtaining the provider client via an untyped attribute rather than via injection, or a new method on the security identity?
<3> Get the current authorization code flow access token and revoke it. | ||
<4> Get the current authorization code flow refresh token and revoke it. | ||
|
||
Alternatively, when you do a local logout with <<oidc-session,OidcSession>>, you can inject `OidcProviderClient`, `AccessTokenCredential` and `RefreshToken`. |
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 looks more useful, as a use-case, because for client-side logouts, the tokens won't be automatically invalidated by the server.
@GET | ||
@Path("logout") | ||
public String logout() { | ||
oidcSession.logout().await().indefinitely(); <1> |
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.
Are we sure it's better to show a sync endpoint method doing 3 await().indefinitely()
rather than show a reactive endpoint with composition?
Opinions, @geoand @cescoffier ?
Fixes #44157.
@sschellh asked about an option for the user code be able to revoke tokens (I guess, either access or refresh tokens or both) when one of the Logout events is observed.
It reminded me that in Renarde, for the Apple authentication, this is also a typical requirement.
So this PR:
OidcProviderClient
which is used byquarkus-oidc
, both injectable and also accessible as aSecurityIdentity
attributeSecurityEvent
listeners can react to logout, and other events like authentication failure, by usingOidcProviderClient
to revoke tokens if they need to - test is providedinjected
OidcProviderClient
to revoke tokens or do additional actions like token introspection. For example, Renarde code can have@Inject OidcSession session;
, logout, and then follow up with revoking tokens.The only remaining thing that I believe should be done is that
OidcProviderClient
should become an API interface, with the runtime subpackage providing an implementation