3.2.7. OIDC redirect filters


You can register one or more io.quarkus.oidc.OidcRedirectFilter implementations to filter OIDC redirects to OIDC authorization and logout endpoints but also local redirects to custom error and session expired pages. Custom OidcRedirectFilter can add additional query parameters, response headers and set new cookies.

For example, the following simple custom OidcRedirectFilter adds an additional query parameter and a custom response header for all redirect requests that can be done by Quarkus OIDC:

package io.quarkus.it.keycloak;

import jakarta.enterprise.context.ApplicationScoped;

import io.quarkus.arc.Unremovable;
import io.quarkus.oidc.OidcRedirectFilter;

@ApplicationScoped
@Unremovable
public class GlobalOidcRedirectFilter implements OidcRedirectFilter {

    @Override
    public void filter(OidcRedirectContext context) {
        if (context.redirectUri().contains("/session-expired-page")) {
            context.additionalQueryParams().add("redirect-filtered", "true,"); 
1

            context.routingContext().response().putHeader("Redirect-Filtered", "true"); 
2

        }
    }

}
1
Add an additional query parameter. Note the queury names and values are URL-encoded by Quarkus OIDC, a redirect-filtered=true%20C query parameter is added to the redirect URI in this case.
2
Add a custom HTTP response header.

See also the Customizing authentication requests section how to configure additional query parameters for OIDC authorization point.

Custom OidcRedirectFilter for local error and session expired pages can also create secure cookies to help with generating such pages.

For example, let’s assume you need to redirect the current user whose session has expired to a custom session expired page available at http://localhost:8080/session-expired-page. The following custom OidcRedirectFilter encrypts the user name in a custom session_expired cookie using an OIDC tenant client secret:

package io.quarkus.it.keycloak;

import jakarta.enterprise.context.ApplicationScoped;

import org.eclipse.microprofile.jwt.Claims;

import io.quarkus.arc.Unremovable;
import io.quarkus.oidc.AuthorizationCodeTokens;
import io.quarkus.oidc.OidcRedirectFilter;
import io.quarkus.oidc.Redirect;
import io.quarkus.oidc.Redirect.Location;
import io.quarkus.oidc.TenantFeature;
import io.quarkus.oidc.runtime.OidcUtils;
import io.smallrye.jwt.build.Jwt;

@ApplicationScoped
@Unremovable
@TenantFeature("tenant-refresh")
@Redirect(Location.SESSION_EXPIRED_PAGE) 
1

public class SessionExpiredOidcRedirectFilter implements OidcRedirectFilter {

    @Override
    public void filter(OidcRedirectContext context) {

        if (context.redirectUri().contains("/session-expired-page")) {
        AuthorizationCodeTokens tokens = context.routingContext().get(AuthorizationCodeTokens.class.getName()); 
2

        String userName = OidcUtils.decodeJwtContent(tokens.getIdToken()).getString(Claims.preferred_username.name()); 
3

        String jwe = Jwt.preferredUserName(userName).jwe()
                .encryptWithSecret(context.oidcTenantConfig().credentials.secret.get()); 
4

        OidcUtils.createCookie(context.routingContext(), context.oidcTenantConfig(), "session_expired",
                jwe + "|" + context.oidcTenantConfig().tenantId.get(), 10); 
5

     }
    }
}
1
Make sure this redirect filter is only called during a redirect to the session expired page.
2
Access AuthorizationCodeTokens tokens associated with the now expired session as a RoutingContext attribute.
3
Decode ID token claims and get a user name.
4
Save the user name in a JWT token encrypted with the current OIDC tenant’s client secret.
5
Create a custom session_expired cookie valid for 5 seconds which joins the encrypted token and a tenant id using a "|" separator. Recording a tenant id in a custom cookie can help to generate correct session expired pages in a multi-tenant OIDC setup.

Next, a public JAX-RS resource which generates session expired pages can use this cookie to create a page tailored for this user and the corresponding OIDC tenant, for example:

package io.quarkus.it.keycloak;

import jakarta.inject.Inject;
import jakarta.ws.rs.CookieParam;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;

import org.eclipse.microprofile.jwt.Claims;
import org.eclipse.microprofile.jwt.JsonWebToken;

import io.quarkus.oidc.OidcTenantConfig;
import io.quarkus.oidc.runtime.OidcUtils;
import io.quarkus.oidc.runtime.TenantConfigBean;
import io.smallrye.jwt.auth.principal.DefaultJWTParser;
import io.vertx.ext.web.RoutingContext;

@Path("/session-expired-page")
public class SessionExpiredResource {
    @Inject
    RoutingContext context;

    @Inject
    TenantConfigBean tenantConfig; 
1


    @GET
    public String sessionExpired(@CookieParam("session_expired") String sessionExpired) throws Exception {
        // Cookie format: jwt|<tenant id>

        String[] pair = sessionExpired.split("\\|"); 
2

        OidcTenantConfig oidcConfig = tenantConfig.getStaticTenantsConfig().get(pair[1]).getOidcTenantConfig(); 
3

        JsonWebToken jwt = new DefaultJWTParser().decrypt(pair[0], oidcConfig.credentials.secret.get()); 
4

        OidcUtils.removeCookie(context, oidcConfig, "session_expired"); 
5

        return jwt.getClaim(Claims.preferred_username) + ", your session has expired. "
                + "Please login again at http://localhost:8081/" + oidcConfig.tenantId.get(); 
6

    }
}
1
Inject TenantConfigBean which can be used to access all the current OIDC tenant configurations.
2
Split the custom cookie value into 2 parts, first part is the encrypted token, last part is the tenant id.
3
Get the OIDC tenant configuration.
4
Decrypt the cookie value using the OIDC tenant’s client secret.
5
Remove the custom cookie.
6
Use the username in the decrypted token and the tenant id to generate the service expired page response.
Red Hat logoGithubredditYoutubeTwitter

詳細情報

試用、購入および販売

コミュニティー

会社概要

Red Hat は、企業がコアとなるデータセンターからネットワークエッジに至るまで、各種プラットフォームや環境全体で作業を簡素化できるように、強化されたソリューションを提供しています。

多様性を受け入れるオープンソースの強化

Red Hat では、コード、ドキュメント、Web プロパティーにおける配慮に欠ける用語の置き換えに取り組んでいます。このような変更は、段階的に実施される予定です。詳細情報: Red Hat ブログ.

Red Hat ドキュメントについて

Legal Notice

Theme

© 2026 Red Hat
トップに戻る