Class OAuth2BearerTokenVerifier

java.lang.Object
com.kingsrook.qqq.backend.core.modules.authentication.implementations.OAuth2BearerTokenVerifier

public class OAuth2BearerTokenVerifier extends Object
Verifies an `Authorization: Bearer ` access token issued by the app's OAuth2 / OIDC provider, without a server-side session. A token is accepted only when ALL of these hold: - it is a signed JWT (JWS); `alg: none`, unsigned (plain) and encrypted tokens, and symmetric (HS*) algorithms are refused; - its `iss` is one of the trusted issuers: the app's provider (baseUrl), or the native client's provider (nativeClientBaseUrl); - its signature verifies against that issuer's published JWKS, fetched from the jwks_uri of the issuer's OIDC discovery document. Keys are cached and refetched (rate limited) when a token names an unknown key id, so key rotation needs no restart; - its `aud` contains an accepted client id for that issuer: clientId and additionalBearerAudiences for the app's issuer, nativeClientId for the native issuer; - it has `exp` in the future and `nbf` (if any) in the past, with MAX_CLOCK_SKEW_SECONDS of tolerance, and lives no longer than bearerTokenMaxLifetimeSeconds (exp - iat, or exp - now without iat); - it is an access token, not an ID token: no `nonce` or `at_hash`, and at least one of `scope`, `azp`, `client_id` (typ `at+jwt` is accepted too); - it has a non-blank `sub` (machine tokens without one only when bearerMachineTokenUsernameSubject is on, then `preferred_username`). Before any network call, the token's (unverified) `iss` must equal one of the configured issuers, so a forged token cannot trigger discovery. The discovery document's issuer must equal the configured one (OIDC Discovery section 4.3). A failed discovery is cached with backoff (30 s doubling to 5 minutes), so a provider outage is not amplified by requests. Errors never reveal which check failed (they are logged at debug level).
  • Field Details

  • Constructor Details

    • OAuth2BearerTokenVerifier

      public OAuth2BearerTokenVerifier()
  • Method Details

    • getConfiguredIssuers

      public static List<OAuth2BearerTokenVerifier.ConfiguredIssuer> getConfiguredIssuers(OAuth2AuthenticationMetaData metaData)
      The issuers an app trusts: its own (baseUrl, whose public issuer is externalBaseUrl when set) and, when set, its native client's.
    • getTrustedIssuerAudiences

      public static Map<String,Set<String>> getTrustedIssuerAudiences(OAuth2AuthenticationMetaData metaData)
      The (issuer discovery base -> accepted audiences) pairs for an app. Empty unless bearerTokensEnabled is true (opt-in).
    • verify

      public com.nimbusds.jwt.JWTClaimsSet verify(String token, OAuth2AuthenticationMetaData metaData) throws QAuthenticationException
      Verify a bearer token; return its claims.
      Throws:
      QAuthenticationException - (always with REJECTED_MESSAGE) when the token fails any check, or the provider's keys cannot be loaded.
    • buildKeySource

      public static com.nimbusds.jose.jwk.source.JWKSource<com.nimbusds.jose.proc.SecurityContext> buildKeySource(URL jwksUrl, com.nimbusds.jose.util.ResourceRetriever retriever)
      The caching, rotation-aware JWK source for a jwks_uri.
    • buildKeySource

      public static com.nimbusds.jose.jwk.source.JWKSource<com.nimbusds.jose.proc.SecurityContext> buildKeySource(URL jwksUrl, com.nimbusds.jose.util.ResourceRetriever retriever, long minMillisBetweenFetches)
      The caching, rotation-aware JWK source for a jwks_uri, with a given minimum interval between fetches.
    • setIssuerResolverForTests

      public static void setIssuerResolverForTests(Function<String,OAuth2BearerTokenVerifier.TrustedIssuer> resolver)
      For tests: replace discovery (base url -> trusted issuer), and clear the cache. Pass null to restore OIDC discovery.
    • clearCache

      public static void clearCache()
      Forget discovered issuers and their cached keys.
    • getAcceptedAudiences

      public static List<String> getAcceptedAudiences(OAuth2AuthenticationMetaData metaData)
      For diagnostics: the accepted audiences as a flat list.