Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions distribution/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,8 @@
<argument>-c</argument>
<argument>org.apache.druid.extensions:druid-pac4j</argument>
<argument>-c</argument>
<argument>org.apache.druid.extensions:druid-pac4j-v5</argument>
<argument>-c</argument>
<argument>org.apache.druid.extensions:druid-ranger-security</argument>
<argument>-c</argument>
<argument>org.apache.druid.extensions:druid-kubernetes-extensions</argument>
Expand Down
3 changes: 2 additions & 1 deletion docs/configuration/extensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ Core extensions are maintained by Druid committers.
|mysql-metadata-storage|MySQL metadata store.|[link](../development/extensions-core/mysql.md)|
|postgresql-metadata-storage|PostgreSQL metadata store.|[link](../development/extensions-core/postgresql.md)|
|simple-client-sslcontext|Simple SSLContext provider module to be used by Druid's internal HttpClient when talking to other Druid processes over HTTPS.|[link](../development/extensions-core/simple-client-sslcontext.md)|
|druid-pac4j|OpenID Connect authentication for druid processes.|[link](../development/extensions-core/druid-pac4j.md)|
|druid-pac4j|OpenID Connect authentication for druid processes.|[link](../development/extensions-core/druid-pac4j.md)| | [link](../development/extensions-core/druid-pac4j.md) |
| druid-pac4j-v5| OpenID Connect authentication for druid processes. Uses version 5 or above for pac4j. Incompatible with JDK8. | | [link](../development/extensions-core/druid-pac4j-v5.md) |
|druid-kubernetes-extensions|Druid cluster deployment on Kubernetes without Zookeeper.|[link](../development/extensions-core/kubernetes.md)|

## Community extensions
Expand Down
57 changes: 57 additions & 0 deletions docs/development/extensions-core/druid-pac4j-v5.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
id: druid-pac4j-v5
title: "Druid pac4j based Security extension which uses pac4j v5+"
---

<!--
~ Licensed to the Apache Software Foundation (ASF) under one
~ or more contributor license agreements. See the NOTICE file
~ distributed with this work for additional information
~ regarding copyright ownership. The ASF licenses this file
~ to you under the Apache License, Version 2.0 (the
~ "License"); you may not use this file except in compliance
~ with the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->


Apache Druid Extension to enable [OpenID Connect](https://openid.net/connect/) based Authentication for Druid Processes using [pac4j](https://github.com/pac4j/pac4j) as the underlying client library.
This can be used with any authentication server that supports same e.g. [Okta](https://developer.okta.com/).
The pac4j authenticator should only be used at the router node to enable a group of users in existing authentication server to interact with Druid cluster, using the [web console](../../operations/web-console.md).

This extension also provides a JWT authenticator that validates [ID Tokens](https://openid.net/specs/openid-connect-core-1_0.html#CodeIDToken) associated with a request. ID Tokens are attached to the request under the `Authorization` header with the bearer token prefix - `Bearer `. This authenticator is intended for services to talk to Druid by initially authenticating with an OIDC server to retrieve the ID Token which is then attached to every Druid request.

This extension does not support JDBC client authentication.

## Configuration

### Creating an Authenticator
```
#Create a pac4j web user authenticator
druid.auth.authenticatorChain=["pac4j"]
druid.auth.authenticator.pac4j.type=pac4j

#Create a JWT token authenticator
druid.auth.authenticatorChain=["jwt"]
druid.auth.authenticator.jwt.type=jwt
```

### Properties
|Property|Description|Default|required|
|--------|---------------|-----------|-------|
|`druid.auth.pac4j.cookiePassphrase`|passphrase for encrypting the cookies used to manage authentication session with browser. It can be provided as plaintext string or The [Password Provider](../../operations/password-provider.md).|none|Yes|
|`druid.auth.pac4j.readTimeout`|Socket connect and read timeout duration used when communicating with authentication server|PT5S|No|
|`druid.auth.pac4j.enableCustomSslContext`|Whether to use custom SSLContext setup via [simple-client-sslcontext](simple-client-sslcontext.md) extension which must be added to extensions list when this property is set to true.|false|No|
|`druid.auth.pac4j.oidc.clientID`|OAuth Client Application id.|none|Yes|
|`druid.auth.pac4j.oidc.clientSecret`|OAuth Client Application secret. It can be provided as plaintext string or The [Password Provider](../../operations/password-provider.md).|none|Yes|
|`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|
176 changes: 176 additions & 0 deletions extensions-core/druid-pac4j-v5/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Licensed to the Apache Software Foundation (ASF) under one
~ or more contributor license agreements. See the NOTICE file
~ distributed with this work for additional information
~ regarding copyright ownership. The ASF licenses this file
~ to you under the Apache License, Version 2.0 (the
~ "License"); you may not use this file except in compliance
~ with the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>org.apache.druid.extensions</groupId>
<artifactId>druid-pac4j-v5</artifactId>
<name>druid-pac4j-v5</name>
<description>druid-pac4j-v5</description>

<parent>
<groupId>org.apache.druid</groupId>
<artifactId>druid</artifactId>
<version>31.0.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

<properties>
<java.version>11</java.version>
<pac4j.version>5.7.3</pac4j.version>

<!-- Following must be updated along with any updates to pac4j version. One can find the compatible version of nimbus libraries in org.pac4j:pac4j-oidc dependencies-->
<nimbus.lang.tag.version>1.7</nimbus.lang.tag.version>
<nimbus.jose.jwt.version>9.37.2</nimbus.jose.jwt.version>
<oauth2.oidc.sdk.version>10.1</oauth2.oidc.sdk.version>
</properties>

<dependencies>
<dependency>
<groupId>org.apache.druid</groupId>
<artifactId>druid-server</artifactId>
<version>${project.parent.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.druid</groupId>
<artifactId>druid-processing</artifactId>
<version>${project.parent.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.pac4j</groupId>
<artifactId>pac4j-oidc</artifactId>
<version>${pac4j.version}</version>
<exclusions>
<!-- pac4j-oidc erroneously declares mockito as a compile time instead of test dependency -->
<exclusion>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>com.nimbusds</groupId>
<artifactId>lang-tag</artifactId>
<version>${nimbus.lang.tag.version}</version>
</dependency>
<dependency>
<groupId>com.nimbusds</groupId>
<artifactId>nimbus-jose-jwt</artifactId>
<version>${nimbus.jose.jwt.version}</version>
</dependency>
<dependency>
<groupId>com.nimbusds</groupId>
<artifactId>oauth2-oidc-sdk</artifactId>
<version>${oauth2.oidc.sdk.version}</version>
</dependency>

<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.pac4j</groupId>
<artifactId>pac4j-core</artifactId>
<version>${pac4j.version}</version>
</dependency>
<dependency>
<groupId>org.pac4j</groupId>
<artifactId>pac4j-javaee</artifactId>
<version>${pac4j.version}</version>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<configuration>
<ignoredUnusedDeclaredDependencies>
<!-- Transitive dependency explicitly added to lock a specific version -->
<ignoredUnusedDeclaredDependency>com.nimbusds:lang-tag</ignoredUnusedDeclaredDependency>
</ignoredUnusedDeclaredDependencies>
</configuration>
</plugin>
</plugins>
</build>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.apache.druid.security.pac4j;


import com.google.common.primitives.Ints;
import com.nimbusds.jose.util.DefaultResourceRetriever;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSocketFactory;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;


/**
* This class exists only to enable use of custom SSLSocketFactory on top of builtin class. This could be removed
* when same functionality has been added to original class com.nimbusds.jose.util.DefaultResourceRetriever.
*/
public class CustomSSLResourceRetriever extends DefaultResourceRetriever
{
private SSLSocketFactory sslSocketFactory;

public CustomSSLResourceRetriever(long readTimeout, SSLSocketFactory sslSocketFactory)
{
// super(..) has to be the very first statement in constructor.
super(Ints.checkedCast(readTimeout), Ints.checkedCast(readTimeout));

this.sslSocketFactory = sslSocketFactory;
}

@Override
protected HttpURLConnection openConnection(final URL url) throws IOException
{
HttpURLConnection con = super.openConnection(url);

if (sslSocketFactory != null && con instanceof HttpsURLConnection) {
((HttpsURLConnection) con).setSSLSocketFactory(sslSocketFactory);
}

return con;
}
}
Loading