From 4210c4b113ca97c41220795f7b0b67c02d331310 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Sun, 26 Apr 2026 01:56:20 +0200 Subject: [PATCH 1/3] Fix jwt-authentication-plugin.adoc documentation bugs - blockUnknown default corrected from true to false throughout; the wrong default was introduced by apache/lucene-solr#805 (SOLR-13649), a docs-only change that never reflected the actual code (getOrDefault(..., false)). Intro paragraph, parameter table, and complex-example callout all fixed. blockUnknown:true restored in the JWKS URL and Admin UI examples that the same commit had removed, so production configs clearly show the recommended setting. - aud default corrected: no clientId fallback exists; audience validation is skipped entirely when aud is not configured. - adminUiScope: document the second fallback to the hardcoded string "solr". - requireExp: document the 30-second clock-skew tolerance. --- .../pages/jwt-authentication-plugin.adoc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/solr/solr-ref-guide/modules/deployment-guide/pages/jwt-authentication-plugin.adoc b/solr/solr-ref-guide/modules/deployment-guide/pages/jwt-authentication-plugin.adoc index 9c8551033f1..6debc9d349f 100644 --- a/solr/solr-ref-guide/modules/deployment-guide/pages/jwt-authentication-plugin.adoc +++ b/solr/solr-ref-guide/modules/deployment-guide/pages/jwt-authentication-plugin.adoc @@ -42,9 +42,7 @@ The simplest possible `security.json` for registering the plugin without configu } ---- -The plugin will by default require a valid JWT token for all traffic. - -If the `blockUnknown` property is set to `false` as in the above example, it is possible to start configuring the plugin using unauthenticated REST API calls, which is further described in section <>. +By default (`blockUnknown=false`), requests without a JWT are allowed through, which makes it possible to configure the plugin using unauthenticated REST API calls as described in <>. Set `blockUnknown=true` to require a valid JWT for all requests. == Configuration Parameters @@ -52,17 +50,17 @@ If the `blockUnknown` property is set to `false` as in the above example, it is [%header,format=csv,separator=;,cols="25%,50%,25%"] |=== Key ; Description ; Default -blockUnknown ; Set to `false` to if you need to perform configuration through REST API or if you use an Authorization Plugin and only want certain paths protected. By default all requests will require a token ; `true` +blockUnknown ; Controls whether requests without a JWT are blocked (`true`) or passed through (`false`). Set to `true` to enforce authentication on all requests. Set to `false` when you need to configure the plugin via unauthenticated REST API calls, or when an Authorization Plugin is used for path-level access control. ; `false` realm ; Name of the authentication realm to echo back in HTTP 401 responses. Will also be displayed in Admin UI login page ; 'solr-jwt' scope ; Whitespace separated list of valid scopes. If configured, the JWT access token MUST contain a `scope` claim with at least one of the listed scopes. Example: `solr:read solr:admin` ; requireIss ; Fails requests that lacks an `iss` (issuer) claim ; `true` -requireExp ; Fails requests that lacks an `exp` (expiry time) claim ; `true` +requireExp ; Fails requests that lacks an `exp` (expiry time) claim. A clock skew tolerance of 30 seconds is applied, so tokens expired within the last 30 seconds are still accepted. ; `true` algAllowlist ; JSON array with algorithms to accept: `HS256`, `HS384`, `HS512`, `RS256`, `RS384`, `RS512`, `ES256`, `ES384`, `ES512`, `PS256`, `PS384`, `PS512`, `none ; Default is to allow all algorithms jwkCacheDur ; Duration of JWK cache in seconds ; `3600` (1 hour) principalClaim ; What claim id to pull principal from ; `sub` rolesClaim ; What claim id to pull user roles from. Both top-level claim and nested claim is supported. Use `someClaim.child` syntax to address a claim `child` nested within the `someClaim` object. The claim must then either contain a space separated list of roles or a JSON array. The roles can then be used to define fine-grained access in an Authorization plugin ; By default the scopes from `scope` claim are passed on as user roles claimsMatch ; JSON object of claims (key) that must match a regular expression (value). Example: `{ "foo" : "A|B" }` will require the `foo` claim to be either "A" or "B". ; -adminUiScope ; Define what scope is requested when logging in from Admin UI ; If not defined, the first scope from `scope` parameter is used +adminUiScope ; Define what scope is requested when logging in from Admin UI ; If not defined, falls back to the first entry in `scope` if configured, otherwise to the hardcoded value `solr` redirectUris ; Valid location(s) for redirect after external authentication. Takes a string or array of strings. Must be the base URL of Solr, e.g., https://solr1.example.com:8983/solr/ and must match the list of redirect URIs registered with the Identity Provider beforehand. ; Defaults to empty list, i.e., any node is assumed to be a valid redirect target. trustedCerts ; One or more X.509 SSL certificates in plaintext PEM or PKCS#7 formats, that should be trusted when talking to IdPs. Newlines must be replaced with `\n`. See paragraph <> for more about its usage. ; Defaults to Java truststore trustedCertsFile ; Path to a file of type PEM, DER or PKCS#7, containing one or more X.509 SSL certificates that should be trusted when talking to IdPs. Can also be an array of file paths. See paragraph <> for more about its usage. ; Defaults to Java truststore @@ -84,7 +82,7 @@ clientId ; Client identifier for use with OpenID Connect. Required t jwksUrl ; A URL to a https://tools.ietf.org/html/rfc7517#section-5[JWKs] endpoint. Must use https protocol. Optionally an array of URLs in which case all public keys from all URLs will be consulted when validating signatures. ; Auto configured if `wellKnownUrl` is provided jwk ; As an alternative to `jwksUrl` you may provide a static JSON object containing the public key(s) of the issuer. The format is either JWK or JWK Set, see https://tools.ietf.org/html/rfc7517#appendix-A[RFC7517] for examples. ; iss ; Unique issuer id as configured on the IdP. Incoming tokens must have a matching `iss` claim. Also used to resolve issuer when multiple issuers configured. ; Auto configured if `wellKnownUrl` is provided -aud ; Validates that the `aud` (audience) claim equals this string ; Uses `clientId` if configured +aud ; Validates that the `aud` (audience) claim equals this string ; If not set, audience validation is skipped entirely authorizationEndpoint; The URL for the Id Provider's authorization endpoint ; Auto configured if `wellKnownUrl` is provided tokenEndpoint; The URL for the Id Provider's token endpoint ; Auto configured if `wellKnownUrl` is provided authorizationFlow; Specifies the OAuth 2.0 flow to be used. Supported flows are 'implicit' and 'code_pkce' (for authorization code with 'Proof Key for Code Exchange'). Note: 'implicit' is deprecated and it is highly recommended to use 'code_pkce' instead. ; implicit @@ -105,6 +103,7 @@ Below is an example of the former: { "authentication": { "class": "solr.JWTAuthPlugin", + "blockUnknown": true, "jwksUrl": "https://my.key.server/jwk.json" } } @@ -118,6 +117,7 @@ This example shows configuration using https://openid.net/specs/openid-connect-d { "authentication": { "class": "solr.JWTAuthPlugin", + "blockUnknown": true, "wellKnownUrl": "https://idp.example.com/.well-known/openid-configuration", "clientId": "xyz", "redirectUris": "https://my.solr.server:8983/solr/" @@ -167,7 +167,7 @@ Let's look at a more complex configuration, this time with two issuers configure Let's comment on this config: <1> Plugin class -<2> Make sure to block anyone without a valid token (this is also the default) +<2> Block requests without a valid token. This must be set explicitly — the default is `false` <3> Fetch the user id from another claim than the default `sub` <4> Require that the `foo` claim is one of "A" or "B" and that the `dept` claim is "IT" <5> Require one of the scopes `solr:read`, `solr:write` or `solr:admin` From e1e5624d4bee6b8f959154736b7894b7b52dd727 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Sun, 26 Apr 2026 13:16:31 +0200 Subject: [PATCH 2/3] Clarify some docs --- .../deployment-guide/pages/jwt-authentication-plugin.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/solr/solr-ref-guide/modules/deployment-guide/pages/jwt-authentication-plugin.adoc b/solr/solr-ref-guide/modules/deployment-guide/pages/jwt-authentication-plugin.adoc index 6debc9d349f..383efbee1f7 100644 --- a/solr/solr-ref-guide/modules/deployment-guide/pages/jwt-authentication-plugin.adoc +++ b/solr/solr-ref-guide/modules/deployment-guide/pages/jwt-authentication-plugin.adoc @@ -37,7 +37,7 @@ The simplest possible `security.json` for registering the plugin without configu { "authentication": { "class":"solr.JWTAuthPlugin", - "blockUnknown":"false" + "blockUnknown": false } } ---- @@ -82,7 +82,7 @@ clientId ; Client identifier for use with OpenID Connect. Required t jwksUrl ; A URL to a https://tools.ietf.org/html/rfc7517#section-5[JWKs] endpoint. Must use https protocol. Optionally an array of URLs in which case all public keys from all URLs will be consulted when validating signatures. ; Auto configured if `wellKnownUrl` is provided jwk ; As an alternative to `jwksUrl` you may provide a static JSON object containing the public key(s) of the issuer. The format is either JWK or JWK Set, see https://tools.ietf.org/html/rfc7517#appendix-A[RFC7517] for examples. ; iss ; Unique issuer id as configured on the IdP. Incoming tokens must have a matching `iss` claim. Also used to resolve issuer when multiple issuers configured. ; Auto configured if `wellKnownUrl` is provided -aud ; Validates that the `aud` (audience) claim equals this string ; If not set, audience validation is skipped entirely +aud ; Validates that the `aud` (audience) claim equals this string. When set on any issuer, all tokens must include a matching `aud` claim. ; If no issuer configures `aud`, audience validation is skipped for all tokens authorizationEndpoint; The URL for the Id Provider's authorization endpoint ; Auto configured if `wellKnownUrl` is provided tokenEndpoint; The URL for the Id Provider's token endpoint ; Auto configured if `wellKnownUrl` is provided authorizationFlow; Specifies the OAuth 2.0 flow to be used. Supported flows are 'implicit' and 'code_pkce' (for authorization code with 'Proof Key for Code Exchange'). Note: 'implicit' is deprecated and it is highly recommended to use 'code_pkce' instead. ; implicit From e950cd70ef61261980b7770ede3b795bfba26689 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Tue, 28 Apr 2026 10:26:54 +0200 Subject: [PATCH 3/3] Adapt the docs to reflect the default 'true' for blockUnknown --- .../deployment-guide/pages/jwt-authentication-plugin.adoc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/solr/solr-ref-guide/modules/deployment-guide/pages/jwt-authentication-plugin.adoc b/solr/solr-ref-guide/modules/deployment-guide/pages/jwt-authentication-plugin.adoc index 383efbee1f7..40b5d5b5be2 100644 --- a/solr/solr-ref-guide/modules/deployment-guide/pages/jwt-authentication-plugin.adoc +++ b/solr/solr-ref-guide/modules/deployment-guide/pages/jwt-authentication-plugin.adoc @@ -42,7 +42,9 @@ The simplest possible `security.json` for registering the plugin without configu } ---- -By default (`blockUnknown=false`), requests without a JWT are allowed through, which makes it possible to configure the plugin using unauthenticated REST API calls as described in <>. Set `blockUnknown=true` to require a valid JWT for all requests. +The plugin will by default require a valid JWT token for all traffic. + +If the `blockUnknown` property is set to `false` as in the above example, it is possible to start configuring the plugin using unauthenticated REST API calls, which is further described in section <>. == Configuration Parameters @@ -50,7 +52,7 @@ By default (`blockUnknown=false`), requests without a JWT are allowed through, w [%header,format=csv,separator=;,cols="25%,50%,25%"] |=== Key ; Description ; Default -blockUnknown ; Controls whether requests without a JWT are blocked (`true`) or passed through (`false`). Set to `true` to enforce authentication on all requests. Set to `false` when you need to configure the plugin via unauthenticated REST API calls, or when an Authorization Plugin is used for path-level access control. ; `false` +blockUnknown ; Set to `false` to if you need to perform configuration through REST API or if you use an Authorization Plugin and only want certain paths protected. By default all requests will require a token ; `true` realm ; Name of the authentication realm to echo back in HTTP 401 responses. Will also be displayed in Admin UI login page ; 'solr-jwt' scope ; Whitespace separated list of valid scopes. If configured, the JWT access token MUST contain a `scope` claim with at least one of the listed scopes. Example: `solr:read solr:admin` ; requireIss ; Fails requests that lacks an `iss` (issuer) claim ; `true` @@ -167,7 +169,7 @@ Let's look at a more complex configuration, this time with two issuers configure Let's comment on this config: <1> Plugin class -<2> Block requests without a valid token. This must be set explicitly — the default is `false` +<2> Make sure to block anyone without a valid token (this is also the default) <3> Fetch the user id from another claim than the default `sub` <4> Require that the `foo` claim is one of "A" or "B" and that the `dept` claim is "IT" <5> Require one of the scopes `solr:read`, `solr:write` or `solr:admin`