Skip to content

Commit 4e94c06

Browse files
committed
auth0 jwt factory
1 parent c434327 commit 4e94c06

File tree

9 files changed

+434
-0
lines changed

9 files changed

+434
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,6 @@
2121

2222
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
2323
hs_err_pid*
24+
25+
# maven
26+
target

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,21 @@
11
# pulsar-client-plugin
22
Pulsar client plugin for auth0, aws, and etc.
3+
4+
# auth0
5+
6+
Auth0 integration consists of the client side plugin and a broker auth plugin. The client plugin generates an auth0 jwt.
7+
8+
``` java
9+
String domain = "https://<your auth0 domain>.auth0.com/oauth/token";
10+
String clientId = "";
11+
String clientSecret = "";
12+
String audience = "https://useast2.aws.kafkaesque.io";
13+
14+
// Create client object
15+
PulsarClient client = PulsarClient.builder()
16+
.serviceUrl(SERVICE_URL)
17+
.authentication(
18+
AuthFactory.auth0(domain, clientId, clientSecret, audience)
19+
)
20+
.build();
21+
```

java/.vscode/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"java.configuration.updateBuildConfiguration": "automatic"
3+
}

java/.vscode/tasks.json

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
// See https://go.microsoft.com/fwlink/?LinkId=733558
3+
// for the documentation about the tasks.json format
4+
"version": "2.0.0",
5+
"tasks": [
6+
{
7+
"label": "verify",
8+
"type": "shell",
9+
"command": "mvn -B verify",
10+
"group": "build"
11+
},
12+
{
13+
"label": "compile",
14+
"type": "shell",
15+
"command": "mvn -B compile",
16+
"group": "build"
17+
},
18+
{
19+
"label": "test",
20+
"type": "shell",
21+
"command": "mvn -B test",
22+
"group": "test"
23+
}
24+
]
25+
}

java/pom.xml

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
3+
<modelVersion>4.0.0</modelVersion>
4+
<groupId>com.kq.pulsar.client</groupId>
5+
<artifactId>SimpleClient</artifactId>
6+
<packaging>jar</packaging>
7+
<version>1.0-SNAPSHOT</version>
8+
<name>SimpleClient</name>
9+
<url>http://maven.apache.org</url>
10+
<properties>
11+
<maven.compiler.source>1.8</maven.compiler.source>
12+
<maven.compiler.target>1.8</maven.compiler.target>
13+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
14+
<pulsar.version>2.4.1</pulsar.version>
15+
</properties>
16+
<build>
17+
<plugins>
18+
<plugin>
19+
<groupId>org.apache.maven.plugins</groupId>
20+
<artifactId>maven-compiler-plugin</artifactId>
21+
<version>3.8.1</version>
22+
<configuration>
23+
<source>1.8</source>
24+
<target>1.8</target>
25+
</configuration>
26+
</plugin>
27+
</plugins>
28+
</build>
29+
<dependencies>
30+
<dependency>
31+
<groupId>junit</groupId>
32+
<artifactId>junit</artifactId>
33+
<version>3.8.1</version>
34+
<scope>test</scope>
35+
</dependency>
36+
<dependency>
37+
<groupId>com.auth0</groupId>
38+
<artifactId>java-jwt</artifactId>
39+
<version>3.9.0</version>
40+
</dependency>
41+
<dependency>
42+
<groupId>com.auth0</groupId>
43+
<artifactId>jwks-rsa</artifactId>
44+
<version>0.9.0</version>
45+
</dependency>
46+
<dependency>
47+
<groupId>org.apache.pulsar</groupId>
48+
<artifactId>pulsar-client</artifactId>
49+
<version>${pulsar.version}</version>
50+
</dependency>
51+
<dependency>
52+
<groupId>com.google.guava</groupId>
53+
<artifactId>guava</artifactId>
54+
<version>21.0</version>
55+
</dependency>
56+
<!-- dependency>
57+
<groupId>ch.qos.logback</groupId>
58+
<artifactId>logback-classic</artifactId>
59+
<version>1.1.3</version>
60+
</dependency -->
61+
62+
<dependency>
63+
<groupId>com.konghq</groupId>
64+
<artifactId>unirest-java</artifactId>
65+
<version>3.4.00</version>
66+
</dependency>
67+
68+
<dependency>
69+
<groupId>javax.ws.rs</groupId>
70+
<artifactId>javax.ws.rs-api</artifactId>
71+
<version>2.1.1</version>
72+
</dependency>
73+
74+
<dependency>
75+
<groupId>io.jsonwebtoken</groupId>
76+
<artifactId>jjwt-impl</artifactId>
77+
<version>0.10.5</version>
78+
</dependency>
79+
80+
<dependency>
81+
<groupId>io.jsonwebtoken</groupId>
82+
<artifactId>jjwt-jackson</artifactId>
83+
<version>0.10.5</version>
84+
</dependency>
85+
</dependencies>
86+
</project>
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.kq.pulsar.client.auth;
2+
3+
import com.kq.pulsar.client.auth.AuthenticationAuth0;
4+
import com.kq.pulsar.client.auth.auth0.Auth0JWT;
5+
6+
import org.apache.pulsar.client.api.Authentication;
7+
8+
public final class AuthFactory {
9+
10+
private AuthFactory() {}
11+
12+
/**
13+
* Request JWT from autho and pass the JWT to pulsar broker.
14+
* @param domain
15+
* @param clientId
16+
* @param clientSecret
17+
* @param audience
18+
* @return
19+
*/
20+
public static Authentication auth0(String domain, String clientId, String clientSecret, String audience) {
21+
return new AuthenticationAuth0(Auth0JWT.create(domain, clientId, clientSecret, audience).generateAndCheck());
22+
23+
}
24+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package com.kq.pulsar.client.auth;
2+
3+
import com.google.common.base.Charsets;
4+
5+
import java.io.IOException;
6+
import java.net.URI;
7+
import java.nio.file.Files;
8+
import java.nio.file.Paths;
9+
import java.util.Map;
10+
import java.util.function.Supplier;
11+
12+
import org.apache.pulsar.client.api.Authentication;
13+
import org.apache.pulsar.client.api.AuthenticationDataProvider;
14+
import org.apache.pulsar.client.api.EncodedAuthenticationParameterSupport;
15+
import org.apache.pulsar.client.api.PulsarClientException;
16+
17+
/**
18+
* JWT based authentication provider.
19+
*/
20+
public class AuthenticationAuth0 implements Authentication, EncodedAuthenticationParameterSupport {
21+
22+
/**
23+
*
24+
*/
25+
private static final long serialVersionUID = 1L;
26+
private Supplier<String> tokenSupplier;
27+
28+
public AuthenticationAuth0(String token) {
29+
this(() -> token);
30+
}
31+
32+
public AuthenticationAuth0(Supplier<String> tokenSupplier) {
33+
this.tokenSupplier = tokenSupplier;
34+
}
35+
36+
@Override
37+
public void close() throws IOException {
38+
// noop
39+
}
40+
41+
@Override
42+
public String getAuthMethodName() {
43+
return "token";
44+
}
45+
46+
@Override
47+
public AuthenticationDataProvider getAuthData() throws PulsarClientException {
48+
// return new AuthenticationDataToken(tokenSupplier);
49+
return new AuthenticationDataAuth0(tokenSupplier);
50+
}
51+
52+
@Override
53+
public void configure(String encodedAuthParamString) {
54+
// Interpret the whole param string as the token. If the string contains the notation `token:xxxxx` then strip
55+
// the prefix
56+
if (encodedAuthParamString.startsWith("token:")) {
57+
this.tokenSupplier = () -> encodedAuthParamString.substring("token:".length());
58+
} else if (encodedAuthParamString.startsWith("file:")) {
59+
// Read token from a file
60+
URI filePath = URI.create(encodedAuthParamString);
61+
this.tokenSupplier = () -> {
62+
try {
63+
return new String(Files.readAllBytes(Paths.get(filePath)), Charsets.UTF_8).trim();
64+
} catch (IOException e) {
65+
throw new RuntimeException("Failed to read token from file", e);
66+
}
67+
};
68+
} else {
69+
this.tokenSupplier = () -> encodedAuthParamString;
70+
}
71+
}
72+
73+
@Override
74+
public void configure(Map<String, String> authParams) {
75+
// noop
76+
}
77+
78+
@Override
79+
public void start() throws PulsarClientException {
80+
// noop
81+
}
82+
83+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package com.kq.pulsar.client.auth;
2+
3+
import java.util.Map;
4+
5+
import java.util.Set;
6+
import java.util.function.Supplier;
7+
8+
import javax.naming.AuthenticationException;
9+
10+
import org.apache.pulsar.common.api.AuthData;
11+
12+
import org.apache.pulsar.client.api.AuthenticationDataProvider;
13+
14+
import static java.nio.charset.StandardCharsets.UTF_8;
15+
/**
16+
* This plugin requires auth0 token.
17+
*/
18+
public class AuthenticationDataAuth0 implements AuthenticationDataProvider {
19+
20+
/**
21+
*
22+
*/
23+
private static final long serialVersionUID = 1L;
24+
25+
private final Supplier<String> auth0Token;
26+
27+
public AuthenticationDataAuth0(Supplier<String> token) {
28+
auth0Token = token;
29+
}
30+
31+
/*
32+
* HTTP
33+
*/
34+
35+
/**
36+
* Check if data for HTTP are available.
37+
*
38+
* @return true if this authentication data contain data for HTTP
39+
*/
40+
public boolean hasDataForHttp() {
41+
return true;
42+
}
43+
44+
/**
45+
*
46+
* @return a authentication scheme, or {@code null} if the request will not be authenticated.
47+
*/
48+
public String getHttpAuthType() {
49+
return null;
50+
}
51+
52+
/**
53+
*
54+
* @return an enumeration of all the header names
55+
*/
56+
public Set<Map.Entry<String, String>> getHttpHeaders() throws Exception {
57+
return null;
58+
}
59+
60+
/*
61+
* Command
62+
*/
63+
64+
/**
65+
* Check if data from Pulsar protocol are available.
66+
*
67+
* @return true if this authentication data contain data from Pulsar protocol
68+
*/
69+
public boolean hasDataFromCommand() {
70+
return auth0Token.get() != null;
71+
}
72+
73+
/**
74+
*
75+
* @return authentication data which will be stored in a command
76+
*/
77+
public String getCommandData() {
78+
return auth0Token.get();
79+
}
80+
81+
/**
82+
* For mutual authentication, This method use passed in `data` to evaluate and challenge,
83+
* then returns null if authentication has completed;
84+
* returns authenticated data back to server side, if authentication has not completed.
85+
*
86+
* <p>Mainly used for mutual authentication like sasl.
87+
*/
88+
public AuthData authenticate(AuthData data) throws AuthenticationException {
89+
byte[] bytes = (hasDataFromCommand() ? this.getCommandData() : "").getBytes(UTF_8);
90+
return AuthData.of(bytes);
91+
}
92+
93+
}

0 commit comments

Comments
 (0)