Skip to content

Commit

Permalink
Merge pull request #45143 from sberyozkin/oidc_bearer_response_filters
Browse files Browse the repository at this point in the history
Update OIDC bearer doc with a section about response filters
  • Loading branch information
sberyozkin authored Dec 16, 2024
2 parents 45449a2 + e72472f commit 270ae56
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1346,6 +1346,49 @@ Authentication that requires a dynamic tenant will fail.
You can filter OIDC requests made by Quarkus to the OIDC provider by registering one or more `OidcRequestFilter` implementations, which can update or add new request headers, and log requests.
For more information, see xref:security-oidc-code-flow-authentication#code-flow-oidc-request-filters[OIDC request filters].

[[bearer-token-oidc-response-filters]]
=== OIDC response filters

You can filter responses from the OIDC providers by registering one or more `OidcResponseFilter` implementations, which can check the response status, headers and body in order to log them or perform other actions.

You can have a single filter intercepting all the OIDC responses, or use an `@OidcEndpoint` annotation to apply this filter to the specific endpoint responses only. For example:

[source,java]
----
package io.quarkus.it.keycloak;
import jakarta.enterprise.context.ApplicationScoped;
import io.quarkus.arc.Unremovable;
import io.quarkus.logging.Log;
import io.quarkus.oidc.common.OidcEndpoint;
import io.quarkus.oidc.common.OidcEndpoint.Type;
import io.quarkus.oidc.common.OidcResponseFilter;
import io.quarkus.oidc.common.runtime.OidcConstants;
import io.quarkus.oidc.runtime.OidcUtils;
@ApplicationScoped
@Unremovable
@OidcEndpoint(value = Type.DISCOVERY) <1>
public class DiscoveryEndpointResponseFilter implements OidcResponseFilter {
@Override
public void filter(OidcResponseContext rc) {
String contentType = rc.responseHeaders().get("Content-Type"); <2>
if (contentType.equals("application/json") {
String tenantId = rc.requestProperties().get(OidcUtils.TENANT_ID_ATTRIBUTE); <3>
String metadata = rc.responseBody().toString(); <4>
Log.debugf("Tenant %s OIDC metadata: %s", tenantId, metadata);
}
}
}
----
<1> Restrict this filter to requests targeting the OIDC discovery endpoint only.
<2> Check the response `Content-Type` header.
<3> Use `OidcRequestContextProperties` request properties to get the tenant id.
<4> Get the response data as String.

== References

* xref:security-oidc-configuration-properties-reference.adoc[OIDC configuration properties]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -404,9 +404,8 @@ package io.quarkus.it.keycloak;
import jakarta.enterprise.context.ApplicationScoped;
import org.jboss.logging.Logger;
import io.quarkus.arc.Unremovable;
import io.quarkus.logging.Log;
import io.quarkus.oidc.common.OidcEndpoint;
import io.quarkus.oidc.common.OidcEndpoint.Type;
import io.quarkus.oidc.common.OidcResponseFilter;
Expand All @@ -417,16 +416,15 @@ import io.quarkus.oidc.runtime.OidcUtils;
@Unremovable
@OidcEndpoint(value = Type.TOKEN) <1>
public class TokenEndpointResponseFilter implements OidcResponseFilter {
private static final Logger LOG = Logger.getLogger(TokenResponseFilter.class);
@Override
public void filter(OidcResponseContext rc) {
String contentType = rc.responseHeaders().get("Content-Type"); <2>
if (contentType.equals("application/json")
&& OidcConstants.AUTHORIZATION_CODE.equals(rc.requestProperties().get(OidcConstants.GRANT_TYPE)) <3>
&& "code-flow-user-info-cached-in-idtoken".equals(rc.requestProperties().get(OidcUtils.TENANT_ID_ATTRIBUTE)) <3>
&& rc.responseBody().toJsonObject().containsKey("id_token")) { <4>
LOG.debug("Authorization code completed for tenant 'code-flow-user-info-cached-in-idtoken'");
Log.debug("Authorization code completed for tenant 'code-flow-user-info-cached-in-idtoken'");
}
}
}
Expand Down

0 comments on commit 270ae56

Please sign in to comment.