Skip to content

Commit

Permalink
use maven
Browse files Browse the repository at this point in the history
  • Loading branch information
KannarFr committed Nov 26, 2019
0 parents commit b5fb556
Show file tree
Hide file tree
Showing 5 changed files with 544 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
target
.*
59 changes: 59 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<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">
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
<grpc.version>1.18.0</grpc.version>
</properties>

<modelVersion>4.0.0</modelVersion>
<groupId>com.clevercloud</groupId>
<artifactId>biscuit-pulsar</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>biscuit-pulsar</name>
<url>http://maven.apache.org</url>

<dependencies>
<!-- https://mvnrepository.com/artifact/io.vavr/vavr -->
<dependency>
<groupId>io.vavr</groupId>
<artifactId>vavr</artifactId>
<version>0.10.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.pulsar/pulsar-broker -->
<dependency>
<groupId>org.apache.pulsar</groupId>
<artifactId>pulsar-broker</artifactId>
<version>2.4.1</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-all</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-core</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf-lite</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>com.clevercloud</groupId>
<artifactId>biscuit-java</artifactId>
<version>0.1.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package com.clevercloud.biscuitpulsar;

import com.clevercloud.biscuit.crypto.PublicKey;
import com.clevercloud.biscuit.token.Verifier;
import org.apache.pulsar.broker.ServiceConfiguration;
import org.apache.pulsar.broker.authentication.AuthenticationDataSource;
import org.apache.pulsar.broker.authentication.AuthenticationProvider;
import com.clevercloud.biscuit.token.Biscuit;
import com.clevercloud.biscuit.error.Error;

import io.vavr.control.Either;

import javax.naming.AuthenticationException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Base64;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static com.clevercloud.biscuit.token.builder.Utils.*;
import static com.clevercloud.biscuit.token.builder.Utils.s;

public class BiscuitAuthenticationPlugin implements AuthenticationProvider {
private static final Logger log = LoggerFactory.getLogger(BiscuitAuthenticationPlugin.class);
public static final String BISCUIT_SEALING_KEY = "biscuit-pulsar-key";
private PublicKey rootKey;

public void initialize(ServiceConfiguration serviceConfiguration) throws IOException {
log.info("Initialize Apache Pulsar Biscuit authentication plugin");
String key = (String) serviceConfiguration.getProperty("biscuitRootKey");
log.info("got biscuit root key: {}", key);
try {
rootKey = new PublicKey(hexStringToByteArray(key));
} catch (Exception e) {
log.error("could not decode Biscuit root public key: {}", e);
throw new IOException();
}
}

public String getAuthMethodName() {
return "token";
}

public String authenticate(AuthenticationDataSource authenticationDataSource) throws AuthenticationException {
log.info("Authentication data {}", authenticationDataSource);
log.info("Authentication getCommandData {}", authenticationDataSource.getCommandData());
log.info("Authentication getHttpAuthType {}", authenticationDataSource.getHttpAuthType());
log.info("Authentication getPeerAddress {}", authenticationDataSource.getPeerAddress());

List<String> decodedBytes = null;

if (authenticationDataSource.getCommandData() == null) {
String auth = authenticationDataSource.getHttpHeader("Authorization");

if(auth == null) {
throw new AuthenticationException("missing Authorization header");
}
log.info("Authorization HTTP header: {}", auth);
if(auth.startsWith("Bearer ")) {
decodedBytes = Arrays.asList(new String(auth.substring("Bearer ".length())).split(":"));
} else if(auth.startsWith("Basic ")) {
try {
decodedBytes = Arrays.asList(URLDecoder.decode(new String(Base64.getUrlDecoder().decode(auth.substring("Basic ".length()))), StandardCharsets.UTF_8.toString()).split(":"));
} catch (UnsupportedEncodingException e) {
throw new AuthenticationException("cannot decode Authorization header");
}

} else {
throw new AuthenticationException("unrecognized Authorization header");
}
} else {
decodedBytes = Arrays.asList(authenticationDataSource.getCommandData().split(":"));
}

if(!decodedBytes.get(0).equals("biscuit")) {
log.error("invalid token prefix(must be 'biscuit'): {}", decodedBytes.get(0));
throw new AuthenticationException("invalid token prefix(must be 'biscuit')");
}

log.info("Authentication Authorization|| {}", decodedBytes);

Either<Error, Biscuit> deser = Biscuit.from_bytes(Base64.getUrlDecoder().decode(decodedBytes.get(1)));

if(deser.isLeft()) {
throw new AuthenticationException("could not deserialize token");
} else {
Biscuit biscuit = deser.get();
log.info("deserialized token");

if(biscuit.check_root_key(rootKey).isLeft()) {
throw new AuthenticationException("this token was not generated with the expected root key");
}
log.info("checked root key");

byte[] sealed = biscuit.seal(BISCUIT_SEALING_KEY.getBytes()).get();
log.info("token deserialized and sealed");
return "biscuit:" + Base64.getEncoder().encodeToString(sealed);
}
}

public void close() throws IOException {

}

// using that instead of Hex.decodeHex from commons-codec because there's an incompatibility with Pulsar's dependencies
public static byte[] hexStringToByteArray(String hex) {
int l = hex.length();
byte[] data = new byte[l/2];
for (int i = 0; i < l; i += 2) {
data[i/2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4)
+ Character.digit(hex.charAt(i+1), 16));
}
return data;
}
}
Loading

0 comments on commit b5fb556

Please sign in to comment.