Skip to content

Commit

Permalink
Merge pull request #19872 from geoand/oidc-token-polish
Browse files Browse the repository at this point in the history
Improve documentation for token propagation
  • Loading branch information
sberyozkin authored Sep 2, 2021
2 parents 05bebe3 + f3c65af commit b397e44
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 3 deletions.
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

0 comments on commit b397e44

Please sign in to comment.