quarkusio/quarkus · error · OIDCException

SecurityIdentity must have a RoutingContext attribute

Error message

SecurityIdentity must have a RoutingContext attribute

What it means

This is a deliberate test assertion inside the protected JAX-RS resource of the oidc-code-flow integration test. The endpoint verifies that Quarkus OIDC attaches the Vert.x RoutingContext as a SecurityIdentity attribute; if the attribute is missing, the CDI-authenticated identity is malformed and the resource throws OIDCException. It guards against regressions in the OIDC identity augmentation pipeline.

Source

Thrown at integration-tests/oidc-code-flow/src/main/java/io/quarkus/it/keycloak/ProtectedResource.java:136

    @GET
    @Path("configMetadataIdTokenSigningAlgorithms")
    public String configMetadataIdTokenSigningAlgorithms() {
        return configMetadata.getSupportedIdTokenSigningAlgorithms().stream().collect(Collectors.joining(","));
    }

    @GET
    @Path("configMetadataCodeChallengeMethods")
    public String configMetadataCodeChallengeMethods() {
        return configMetadata.getSupportedCodeChallengeMethods().stream().collect(Collectors.joining(","));
    }

    @GET
    public String getName() {
        if (!idTokenCredential.getToken().equals(idToken.getRawToken())) {
            throw new OIDCException("ID token values are not equal");
        }
        if (identity.getAttribute(RoutingContext.class.getName()) == null) {
            throw new OIDCException("SecurityIdentity must have a RoutingContext attribute");
        }
        return idToken.getName();
    }

    @GET
    @Path("tenant-idtoken-only")
    public String getNameIdTokenOnly() {
        return "tenant-idtoken-only:" + getName();
    }

    @GET
    @Path("tenant-id-refresh-token")
    public String getNameIdRefreshTokenOnly() {
        return "tenant-id-refresh-token:" + getName();
    }

    @GET
    @Path("tenant-split-tokens")

View on GitHub (pinned to e1c734241f)

Solutions

  1. Verify the quarkus-oidc and quarkus-vertx-http extensions are on the runtime classpath and unmodified so the default OIDC identity augmentation runs
  2. Check for custom SecurityIdentityAugmentor implementations that build a new SecurityIdentity without propagating existing attributes; propagate attributes from the parent identity
  3. Ensure the request actually passed through the OIDC code-flow authentication (valid session cookie/id token) rather than a fallback permit-all path
  4. Rebuild core/extensions; if this fires in CI on unmodified code, it signals a regression — inspect recent changes to OidcAuthenticationMechanism / SecurityIdentity augmentation
Defensive patterns

Strategy: validation

Validate before calling

if (identity.getAttribute(org.jboss.resteasy.reactive.server.vertx.RoutingContext.class.getName()) == null) { throw new IllegalStateException("RoutingContext attribute missing from SecurityIdentity"); }

Type guard

boolean hasRoutingContext(SecurityIdentity id) { return id != null && id.getAttribute(io.vertx.ext.web.RoutingContext.class.getName()) != null; }

Try / catch

try { return getName(); } catch (javax.ws.rs.OIDCException e) { log.error("identity augmentation failed", e); return Response.status(500).build(); }

Prevention

When it happens

Trigger: GET request reaches ProtectedResource.getName() (the '/' endpoint) after OIDC authentication, but identity.getAttribute(RoutingContext.class.getName()) returns null — i.e. the SecurityIdentity was built without the RoutingContext attribute the OIDC extension normally injects.

Common situations: A change or misconfiguration in the OIDC/HTTP security extensions that skips SecurityIdentityAugmentor execution; testing against a stack where custom identity augmentors replace rather than wrap the default OIDC augmentor; running a modified authentication path in integration tests.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/213239289dc1de3c. Report an issue: GitHub.