Skip to content

Commit 25ab0d2

Browse files
committed
Show how to revoke OIDC tokens from security event listeners
1 parent 55ff02e commit 25ab0d2

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed

docs/src/main/asciidoc/security-oidc-code-flow-authentication.adoc

+58
Original file line numberDiff line numberDiff line change
@@ -1655,6 +1655,64 @@ public class ServiceResource {
16551655
<2> Revoke the authorization code flow access token.
16561656
<3> Revoke the authorization code flow refresh token.
16571657

1658+
You can also revoke tokens in the security event listeners.
1659+
1660+
For example, when your application supports a standard <<user-initiated-logout>>, you can catch a logout event and revoke tokens:
1661+
1662+
[source,java]
1663+
----
1664+
import java.util.concurrent.CompletableFuture;
1665+
import java.util.concurrent.CompletionStage;
1666+
1667+
import io.quarkus.oidc.AccessTokenCredential;
1668+
import io.quarkus.oidc.OidcProviderClient;
1669+
import io.quarkus.oidc.RefreshToken;
1670+
import io.quarkus.oidc.SecurityEvent;
1671+
import io.quarkus.security.identity.SecurityIdentity;
1672+
import io.smallrye.mutiny.Uni;
1673+
import jakarta.enterprise.context.ApplicationScoped;
1674+
import jakarta.enterprise.event.ObservesAsync;
1675+
1676+
@ApplicationScoped
1677+
public class SecurityEventListener {
1678+
1679+
public CompletionStage<Void> processSecurityEvent(@ObservesAsync SecurityEvent event) {
1680+
if (SecurityEvent.Type.OIDC_LOGOUT_RP_INITIATED == event.getEventType()) { <1>
1681+
return revokeTokens(event.getSecurityIdentity()).subscribeAsCompletionStage();
1682+
}
1683+
return CompletableFuture.completedFuture(null);
1684+
}
1685+
private Uni<Void> revokeTokens(SecurityIdentity securityIdentity) {
1686+
return Uni.join().all(
1687+
revokeAccessToken(securityIdentity),
1688+
revokeRefreshToken(securityIdentity)
1689+
).andCollectFailures()
1690+
.replaceWithVoid()
1691+
.onFailure().recoverWithUni(t -> logFailure(t));
1692+
}
1693+
1694+
private static Uni<Boolean> revokeAccessToken(SecurityIdentity securityIdentity) { <2>
1695+
OidcProviderClient oidcProvider = securityIdentity.getAttribute(OidcProviderClient.class.getName());
1696+
String accessToken = securityIdentity.getCredential(AccessTokenCredential.class).getToken();
1697+
return oidcProvider.revokeAccessToken(accessToken);
1698+
}
1699+
1700+
private static Uni<Boolean> revokeRefreshToken(SecurityIdentity securityIdentity) { <3>
1701+
OidcProviderClient oidcProvider = securityIdentity.getAttribute(OidcProviderClient.class.getName());
1702+
String refreshToken = securityIdentity.getCredential(RefreshToken.class).getToken();
1703+
return oidcProvider.revokeRefreshToken(refreshToken);
1704+
}
1705+
1706+
private static Uni<Void> logFailure(Throwable t) {
1707+
// Log failure as required
1708+
return Uni.createFrom().voidItem();
1709+
}
1710+
}
1711+
----
1712+
<1> Revoke tokens if an RP-initiated logout event is observed.
1713+
<2> Revoke the authorization code flow access token.
1714+
<3> Revoke the authorization code flow refresh token.
1715+
16581716
=== Propagating tokens to downstream services
16591717

16601718
For information about Authorization Code Flow access token propagation to downstream services, see the xref:security-openid-connect-client-reference.adoc#token-propagation-rest[Token Propagation] section.

0 commit comments

Comments
 (0)