This is an automated email from the ASF dual-hosted git repository.
FrankChen021 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/druid.git
The following commit(s) were added to refs/heads/master by this push:
new f92bf482993 Add configurable clientAuthenticationMethod to druid-pac4j
OIDC configuration (#19020)
f92bf482993 is described below
commit f92bf4829935dc05f84597cdc6ca56cf112c11ce
Author: Lukas Krug <[email protected]>
AuthorDate: Sat Apr 25 08:34:00 2026 +0200
Add configurable clientAuthenticationMethod to druid-pac4j OIDC
configuration (#19020)
---
docs/development/extensions-core/druid-pac4j.md | 1 +
.../apache/druid/security/pac4j/OIDCConfig.java | 13 +++++++++-
.../druid/security/pac4j/Pac4jAuthenticator.java | 5 ++++
.../druid/security/pac4j/OIDCConfigTest.java | 28 ++++++++++++++++++++++
4 files changed, 46 insertions(+), 1 deletion(-)
diff --git a/docs/development/extensions-core/druid-pac4j.md
b/docs/development/extensions-core/druid-pac4j.md
index 243350cc51f..a81752cb66a 100644
--- a/docs/development/extensions-core/druid-pac4j.md
+++ b/docs/development/extensions-core/druid-pac4j.md
@@ -55,6 +55,7 @@ druid.auth.authenticator.jwt.type=jwt
|`druid.auth.pac4j.oidc.discoveryURI`|discovery URI for fetching OP metadata
[see this](http://openid.net/specs/openid-connect-discovery-1_0.html).|none|Yes|
|`druid.auth.pac4j.oidc.oidcClaim`|[claim](https://openid.net/specs/openid-connect-core-1_0.html#Claims)
that will be extracted from the ID Token after validation.|name|No|
|`druid.auth.pac4j.oidc.scope`| scope is used by an application during
authentication to authorize access to a user's details.|`openid profile
email`|No|
+|`druid.auth.pac4j.oidc.clientAuthenticationMethod`|The client authentication
method to use when communicating with the OIDC provider. Supported values:
`client_secret_basic`, `client_secret_post`, `client_secret_jwt`,
`private_key_jwt`, `none`. If not specified, pac4j will auto-detect the method
from the provider's discovery document. Set this explicitly if you need to use
a specific method (e.g., when your provider advertises multiple methods but you
want to use a particular one).|Auto [...]
:::info
Users must set a strong passphrase to ensure that an attacker is not able to
guess it simply by brute force.
diff --git
a/extensions-core/druid-pac4j/src/main/java/org/apache/druid/security/pac4j/OIDCConfig.java
b/extensions-core/druid-pac4j/src/main/java/org/apache/druid/security/pac4j/OIDCConfig.java
index 50b04455dbc..d83e04717a0 100644
---
a/extensions-core/druid-pac4j/src/main/java/org/apache/druid/security/pac4j/OIDCConfig.java
+++
b/extensions-core/druid-pac4j/src/main/java/org/apache/druid/security/pac4j/OIDCConfig.java
@@ -44,13 +44,17 @@ public class OIDCConfig
@JsonProperty
private final String scope;
+ @JsonProperty
+ private final String clientAuthenticationMethod;
+
@JsonCreator
public OIDCConfig(
@JsonProperty("clientID") String clientID,
@JsonProperty("clientSecret") PasswordProvider clientSecret,
@JsonProperty("discoveryURI") String discoveryURI,
@JsonProperty("oidcClaim") String oidcClaim,
- @JsonProperty("scope") @Nullable String scope
+ @JsonProperty("scope") @Nullable String scope,
+ @JsonProperty("clientAuthenticationMethod") @Nullable String
clientAuthenticationMethod
)
{
this.clientID = Preconditions.checkNotNull(clientID, "null clientID");
@@ -58,6 +62,7 @@ public class OIDCConfig
this.discoveryURI = Preconditions.checkNotNull(discoveryURI, "null
discoveryURI");
this.oidcClaim = oidcClaim == null ? DEFAULT_SCOPE : oidcClaim;
this.scope = scope;
+ this.clientAuthenticationMethod = clientAuthenticationMethod;
}
@JsonProperty
@@ -89,4 +94,10 @@ public class OIDCConfig
{
return scope;
}
+
+ @JsonProperty
+ public String getClientAuthenticationMethod()
+ {
+ return clientAuthenticationMethod;
+ }
}
diff --git
a/extensions-core/druid-pac4j/src/main/java/org/apache/druid/security/pac4j/Pac4jAuthenticator.java
b/extensions-core/druid-pac4j/src/main/java/org/apache/druid/security/pac4j/Pac4jAuthenticator.java
index ef30f4c7e69..59a6fa0782f 100644
---
a/extensions-core/druid-pac4j/src/main/java/org/apache/druid/security/pac4j/Pac4jAuthenticator.java
+++
b/extensions-core/druid-pac4j/src/main/java/org/apache/druid/security/pac4j/Pac4jAuthenticator.java
@@ -27,6 +27,7 @@ import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.primitives.Ints;
import com.google.inject.Provider;
+import com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod;
import com.nimbusds.oauth2.sdk.http.HTTPRequest;
import org.apache.druid.server.security.AuthenticationResult;
import org.apache.druid.server.security.Authenticator;
@@ -132,6 +133,10 @@ public class Pac4jAuthenticator implements Authenticator
oidcConf.setSecret(oidcConfig.getClientSecret().getPassword());
oidcConf.setDiscoveryURI(oidcConfig.getDiscoveryURI());
oidcConf.setScope(oidcConfig.getScope());
+ if (oidcConfig.getClientAuthenticationMethod() != null) {
+ oidcConf.setClientAuthenticationMethod(
+
ClientAuthenticationMethod.parse(oidcConfig.getClientAuthenticationMethod()));
+ }
oidcConf.setExpireSessionWithToken(true);
oidcConf.setUseNonce(true);
oidcConf.setReadTimeout(Ints.checkedCast(pac4jCommonConfig.getReadTimeout().getMillis()));
diff --git
a/extensions-core/druid-pac4j/src/test/java/org/apache/druid/security/pac4j/OIDCConfigTest.java
b/extensions-core/druid-pac4j/src/test/java/org/apache/druid/security/pac4j/OIDCConfigTest.java
index c4192c020df..0b6128e61bb 100644
---
a/extensions-core/druid-pac4j/src/test/java/org/apache/druid/security/pac4j/OIDCConfigTest.java
+++
b/extensions-core/druid-pac4j/src/test/java/org/apache/druid/security/pac4j/OIDCConfigTest.java
@@ -46,6 +46,7 @@ public class OIDCConfigTest
Assert.assertEquals("testdiscoveryuri", conf.getDiscoveryURI());
Assert.assertEquals("name", conf.getOidcClaim());
Assert.assertEquals("testscope", conf.getScope());
+ Assert.assertNull(conf.getClientAuthenticationMethod());
}
@Test
@@ -72,4 +73,31 @@ public class OIDCConfigTest
Assert.assertEquals("email", conf.getOidcClaim());
Assert.assertEquals("testscope", conf.getScope());
}
+
+ @Test
+ public void testSerdeWithClientAuthenticationMethod() throws Exception
+ {
+ ObjectMapper jsonMapper = new ObjectMapper();
+
+ String jsonStr = "{\n"
+ + " \"clientID\": \"testid\",\n"
+ + " \"clientSecret\": \"testsecret\",\n"
+ + " \"discoveryURI\": \"testdiscoveryuri\",\n"
+ + " \"oidcClaim\": \"email\",\n"
+ + " \"scope\": \"testscope\",\n"
+ + " \"clientAuthenticationMethod\":
\"client_secret_post\"\n"
+ + "}\n";
+
+ OIDCConfig conf = jsonMapper.readValue(
+ jsonMapper.writeValueAsString(jsonMapper.readValue(jsonStr,
OIDCConfig.class)),
+ OIDCConfig.class
+ );
+
+ Assert.assertEquals("testid", conf.getClientID());
+ Assert.assertEquals("testsecret", conf.getClientSecret().getPassword());
+ Assert.assertEquals("testdiscoveryuri", conf.getDiscoveryURI());
+ Assert.assertEquals("email", conf.getOidcClaim());
+ Assert.assertEquals("testscope", conf.getScope());
+ Assert.assertEquals("client_secret_post",
conf.getClientAuthenticationMethod());
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]