From 5695216253a5d720a9e9fdaf8ae8dd10bd65badf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Tue, 28 Apr 2026 09:50:41 +0200 Subject: [PATCH 1/5] JWT auth: change blockUnknown default from false to true The ref-guide documented true as the default, but the code defaulted to false, allowing unauthenticated pass-through. Align the implementation with the documented security behavior. Fix the one unit test (wellKnownConfigNoHeaderPassThrough) that implicitly relied on the old false default by making its blockUnknown=false explicit. Add a note under Solr 10.1 in major-changes-in-solr-10.adoc so upgraders from 10.0 know to set blockUnknown: false if they need pass-through. --- .../java/org/apache/solr/security/jwt/JWTAuthPlugin.java | 2 +- .../org/apache/solr/security/jwt/JWTAuthPluginTest.java | 1 + .../upgrade-notes/pages/major-changes-in-solr-10.adoc | 6 ++++++ solr/webapp/web/js/angular/controllers/security.js | 4 ++-- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/solr/modules/jwt-auth/src/java/org/apache/solr/security/jwt/JWTAuthPlugin.java b/solr/modules/jwt-auth/src/java/org/apache/solr/security/jwt/JWTAuthPlugin.java index 3e60cd71898..ebe1d01de35 100644 --- a/solr/modules/jwt-auth/src/java/org/apache/solr/security/jwt/JWTAuthPlugin.java +++ b/solr/modules/jwt-auth/src/java/org/apache/solr/security/jwt/JWTAuthPlugin.java @@ -171,7 +171,7 @@ public void init(Map pluginConfig) { } blockUnknown = - Boolean.parseBoolean(String.valueOf(pluginConfig.getOrDefault(PARAM_BLOCK_UNKNOWN, false))); + Boolean.parseBoolean(String.valueOf(pluginConfig.getOrDefault(PARAM_BLOCK_UNKNOWN, true))); requireIssuer = Boolean.parseBoolean( String.valueOf(pluginConfig.getOrDefault(PARAM_REQUIRE_ISSUER, "true"))); diff --git a/solr/modules/jwt-auth/src/test/org/apache/solr/security/jwt/JWTAuthPluginTest.java b/solr/modules/jwt-auth/src/test/org/apache/solr/security/jwt/JWTAuthPluginTest.java index 7ee2cc01550..b6b0d9ac273 100644 --- a/solr/modules/jwt-auth/src/test/org/apache/solr/security/jwt/JWTAuthPluginTest.java +++ b/solr/modules/jwt-auth/src/test/org/apache/solr/security/jwt/JWTAuthPluginTest.java @@ -510,6 +510,7 @@ public void wellKnownConfigNoHeaderPassThrough() { .toString(); testConfig.put("wellKnownUrl", wellKnownUrl); testConfig.remove("jwk"); + testConfig.put("blockUnknown", false); plugin.init(testConfig); JWTAuthPlugin.JWTAuthenticationResponse resp = plugin.authenticate(null); assertEquals(PASS_THROUGH, resp.getAuthCode()); diff --git a/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc b/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc index fe6217dd9dd..2c35f877ece 100644 --- a/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc +++ b/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc @@ -43,6 +43,12 @@ Former users of `solr.api.v2.enabled` looking to upgrade to Solr 10.1 or newer s Users who deploy a proxy in front of Solr should also review this setup to ensure that it allows access to the v2 API root path, `/api`. +=== JWT Authentication + +The `blockUnknown` setting in the JWT Authentication plugin now defaults to `true`, meaning requests without a valid JWT token are blocked by default. +In Solr 10.0, the code default was `false` (pass-through), which contradicted the reference guide documentation that described `true` as the default. +Users upgrading from 10.0 who relied on the pass-through behavior must explicitly set `blockUnknown: false` in their `security.json`. + == Solr 10.0 === Solr Jetty parameters diff --git a/solr/webapp/web/js/angular/controllers/security.js b/solr/webapp/web/js/angular/controllers/security.js index 52b5c2ac46a..6880aac977e 100644 --- a/solr/webapp/web/js/angular/controllers/security.js +++ b/solr/webapp/web/js/angular/controllers/security.js @@ -242,7 +242,7 @@ solrAdminApp.controller('SecurityController', function ($scope, $timeout, $cooki $scope.hideAll(); $scope.tls = false; - $scope.blockUnknown = "false"; // default setting + $scope.blockUnknown = "true"; // default setting $scope.realmName = "solr"; $scope.forwardCredentials = "false"; $scope.multiAuthWithBasic = false; @@ -371,7 +371,7 @@ solrAdminApp.controller('SecurityController', function ($scope, $timeout, $cooki //console.log(">> authn: "+JSON.stringify(authn)); - $scope.blockUnknown = authn["blockUnknown"] === true ? "true" : "false"; + $scope.blockUnknown = authn["blockUnknown"] === false ? "false" : "true"; $scope.forwardCredentials = authn["forwardCredentials"] === true ? "true" : "false"; if ("realm" in authn) { From b4204c0e5cb64b29719b463973fab92857e58779 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Tue, 28 Apr 2026 10:05:15 +0200 Subject: [PATCH 2/5] SOLR-18215: Add changelog entry for blockUnknown default change --- .../SOLR-18215-jwt-auth-blockUnknown-default-true.yml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 changelog/unreleased/SOLR-18215-jwt-auth-blockUnknown-default-true.yml diff --git a/changelog/unreleased/SOLR-18215-jwt-auth-blockUnknown-default-true.yml b/changelog/unreleased/SOLR-18215-jwt-auth-blockUnknown-default-true.yml new file mode 100644 index 00000000000..08e26cf170e --- /dev/null +++ b/changelog/unreleased/SOLR-18215-jwt-auth-blockUnknown-default-true.yml @@ -0,0 +1,8 @@ +title: JWT Authentication `blockUnknown` now defaults to `true`, blocking unauthenticated requests by default. Previously the code defaulted to `false` despite the reference guide documenting `true`. Users relying on pass-through must explicitly set `blockUnknown` to `false` in their security.json. +type: changed +authors: + - name: Jan Høydahl + url: https://home.apache.org/phonebook.html?uid=janhoy +links: + - name: SOLR-18215 + url: https://issues.apache.org/jira/browse/SOLR-18215 From b2776adaffc5ae61ffd9e36cc58816f1b26a6292 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Tue, 28 Apr 2026 10:51:19 +0200 Subject: [PATCH 3/5] Update solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../modules/upgrade-notes/pages/major-changes-in-solr-10.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc b/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc index 2c35f877ece..d1bd938d532 100644 --- a/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc +++ b/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc @@ -47,7 +47,7 @@ Users who deploy a proxy in front of Solr should also review this setup to ensur The `blockUnknown` setting in the JWT Authentication plugin now defaults to `true`, meaning requests without a valid JWT token are blocked by default. In Solr 10.0, the code default was `false` (pass-through), which contradicted the reference guide documentation that described `true` as the default. -Users upgrading from 10.0 who relied on the pass-through behavior must explicitly set `blockUnknown: false` in their `security.json`. +Users upgrading from 10.0 who relied on the pass-through behavior must explicitly set `"blockUnknown": false` in their `security.json`. == Solr 10.0 From f9aa38ab26452cd7394b0a4b0f8fc8a41057dd04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Tue, 28 Apr 2026 10:52:25 +0200 Subject: [PATCH 4/5] Update solr/webapp/web/js/angular/controllers/security.js Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- solr/webapp/web/js/angular/controllers/security.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/solr/webapp/web/js/angular/controllers/security.js b/solr/webapp/web/js/angular/controllers/security.js index 6880aac977e..fd65a289988 100644 --- a/solr/webapp/web/js/angular/controllers/security.js +++ b/solr/webapp/web/js/angular/controllers/security.js @@ -371,7 +371,8 @@ solrAdminApp.controller('SecurityController', function ($scope, $timeout, $cooki //console.log(">> authn: "+JSON.stringify(authn)); - $scope.blockUnknown = authn["blockUnknown"] === false ? "false" : "true"; + var blockUnknown = authn["blockUnknown"]; + $scope.blockUnknown = (blockUnknown === false || blockUnknown === "false") ? "false" : "true"; $scope.forwardCredentials = authn["forwardCredentials"] === true ? "true" : "false"; if ("realm" in authn) { From 6f31790f851458c8f68e97491065448070cb1fe6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Tue, 28 Apr 2026 10:56:03 +0200 Subject: [PATCH 5/5] Add a test --- .../org/apache/solr/security/jwt/JWTAuthPluginTest.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/solr/modules/jwt-auth/src/test/org/apache/solr/security/jwt/JWTAuthPluginTest.java b/solr/modules/jwt-auth/src/test/org/apache/solr/security/jwt/JWTAuthPluginTest.java index b6b0d9ac273..ba7aec71d8a 100644 --- a/solr/modules/jwt-auth/src/test/org/apache/solr/security/jwt/JWTAuthPluginTest.java +++ b/solr/modules/jwt-auth/src/test/org/apache/solr/security/jwt/JWTAuthPluginTest.java @@ -483,6 +483,15 @@ public void noHeaderBlockUnknown() { assertEquals(NO_AUTZ_HEADER, resp.getAuthCode()); } + @Test + public void noHeaderDefaultBlocksUnknown() { + // blockUnknown defaults to true — omitting it must block requests without a JWT + testConfig.remove("blockUnknown"); + plugin.init(testConfig); + JWTAuthPlugin.JWTAuthenticationResponse resp = plugin.authenticate(null); + assertEquals(NO_AUTZ_HEADER, resp.getAuthCode()); + } + @Test public void noHeaderNotBlockUnknown() { testConfig.put("blockUnknown", false);