Skip to content
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

Improve documentation for token propagation #19872

Merged
merged 1 commit into from
Sep 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions docs/src/main/asciidoc/security-openid-connect-client.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -596,15 +596,17 @@ quarkus.oidc-client.token-path=/protocol/openid-connect/tokens
[[token-propagation]]
== Token Propagation in MicroProfile RestClient client filter

`quarkus-oidc-token-propagation` extension provide `io.quarkus.oidc.token.propagation.AccessTokenRequestFilter` and `io.quarkus.oidc.token.propagation.JsonWebTokenRequestFilter` JAX-RS ClientRequestFilters which propagates the current link:security-openid-connect[Bearer] or link:security-openid-connect-web-authentication[Authorization Code Flow] access token as an HTTP `Authorization` `Bearer` scheme value.
The `quarkus-oidc-token-propagation` extension provides two JAX-RS `javax.ws.rs.client.ClientRequestFilter` class implementations that simplify the propagation of authentication information.
`io.quarkus.oidc.token.propagation.AccessTokenRequestFilter` propagates the link:security-openid-connect[Bearer] token present in the current active request or the token acquired from the link:security-openid-connect-web-authentication[Authorization Code Flow], as the HTTP `Authorization` header's `Bearer` scheme value.
The `io.quarkus.oidc.token.propagation.JsonWebTokenRequestFilter` provides the same functionality, but in addition provides support for JWT tokens.

When you need to propagate the current Authorization Code Flow access token then the immediate token propagation will work well - as the code flow access tokens (as opposed to ID tokens) are meant to be propagated for the current Quarkus endpoint to access the remote services on behalf of the currently authenticated user.

However, the direct end to end Bearer token propagation should be avoided if possible. For example, `Client -> Service A -> Service B` where `Service B` receives a token sent by `Client` to `Service A`. In such cases `Service B` will not be able to distinguish if the token came from `Service A` or from `Client` directly. For `Service B` to verify the token came from `Service A` it should be able to assert a new issuer and audience claims.

Additionally, a complex application may need to exchange or update the tokens before propagating them. For example, the access context might be different when Service A is accessing Service B. In this case, Service A might be granted a narrow or a completely different set of scopes to access Service B.
Additionally, a complex application may need to exchange or update the tokens before propagating them. For example, the access context might be different when `Service A` is accessing `Service B`. In this case, `Service A` might be granted a narrow or a completely different set of scopes to access `Service B`.

Please see below how both `AccessTokenRequestFilter` and `JsonWebTokenRequestFilter` can help.
The following sections show how `AccessTokenRequestFilter` and `JsonWebTokenRequestFilter` can help.

=== AccessTokenRequestFilter

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* When this annotation is added to a MicroProfile REST Client interface, the {@link AccessTokenRequestFilter} will be added to
* the request pipeline.
* The end result is that the request propagates the Bearer token present in the current active request or the token acquired
* from the Authorization Code Flow,
* as the HTTP {@code Authorization} header's {@code Bearer} scheme value.
*/
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
public class AccessTokenRequestFilter extends AbstractTokenRequestFilter {
private static final String EXCHANGE_SUBJECT_TOKEN = "subject_token";

// note: We can't use constructor injection for these fields because they are registered by RESTEasy
// which doesn't know about CDI at the point of registration

@Inject
Instance<TokenCredential> accessToken;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* When this annotation is added to a MicroProfile REST Client interface, the {@link JsonWebTokenRequestFilter} will be added to
* the request pipeline.
* The end result is that the request propagates the JWT token present in the current active request or the token acquired from
* the Authorization Code Flow,
* as the HTTP {@code Authorization} header's {@code Bearer} scheme value.
*/
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
import io.smallrye.jwt.build.Jwt;

public class JsonWebTokenRequestFilter extends AbstractTokenRequestFilter {

// note: We can't use constructor injection for these fields because they are registered by RESTEasy
// which doesn't know about CDI at the point of registration

@Inject
Instance<org.eclipse.microprofile.jwt.JsonWebToken> jwtAccessToken;

Expand Down