Skip to content

Commit

Permalink
Unit tests work. Reordered parameters of generateJWTToken to match ot…
Browse files Browse the repository at this point in the history
…her methods.
  • Loading branch information
Stephen Agneta committed May 20, 2016
1 parent 4d28eef commit 756858f
Show file tree
Hide file tree
Showing 3 changed files with 217 additions and 9 deletions.
18 changes: 16 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ dependencies {
compile 'org.apache.directory.studio:org.slf4j.log4j12:1.7.2'
compile 'org.apache.logging.log4j:log4j:2.4.1'
compile 'org.lable.rfc3881.auditlogger.adapter:slf4j:1.3'

testCompile 'log4j:log4j:1.2.17'
testCompile 'org.apache.directory.studio:org.slf4j.log4j12:1.7.2'
testCompile 'org.apache.logging.log4j:log4j:2.4.1'
testCompile 'org.lable.rfc3881.auditlogger.adapter:slf4j:1.3'

// http://joel-costigliola.github.io/assertj/
compile 'org.assertj:assertj-core:3.1.0'
Expand Down Expand Up @@ -104,9 +109,18 @@ jar {
instruction 'Bundle-DocURL', 'http://www.bjondinc.com'
instruction 'Bundle-Activator', 'com.bjond.demo.SampleActivator'
}



// Include all of the dependencies. It explodes each jar file into class files and inserts the class files.
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
doFirst {
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
}

// The jose4j uses signed jars which will not match our manifest so I remove them.
// http://stackoverflow.com/a/14441628/3038736
exclude 'META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA'

}


Expand Down Expand Up @@ -154,6 +168,6 @@ task war() {
}

task all() {
dependsOn build, compileTestJava, findbugsMain, findbugsTest
dependsOn build, jar, compileTestJava, findbugsMain, findbugsTest
}

14 changes: 7 additions & 7 deletions src/main/java/com/bjond/jwtutils/JWTUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -95,17 +95,17 @@ public static JwtClaims validateTokenAndProcessClaims(final Key key,


/**
* Generates a JWT Token given a set of parameters common to JWT
* Convenience method that generates a JWT Token given a set of parameters common to JWT
* implementations.
*
* @param bjondServerEncryptionKey
* The Base64 encoded Encyrption key
* @param bjondAdapterSubject
* The indended Subject of the generated token
* @param bjondAdapterAudience
* The intended Audience of the generated token
* @param issuer
* The indended Issuer of the generated token
* @param bjondAdapterAudience
* The intended Audience of the generated token
* @param bjondAdapterSubject
* The indended Subject of the generated token
* @param json
* JSON snippet that will be inserted into the claim under the
* key 'json'
Expand All @@ -118,9 +118,9 @@ public static JwtClaims validateTokenAndProcessClaims(final Key key,
* issue.
*/
public static String generateJWTToken(final String bjondServerEncryptionKey,
final String bjondAdapterSubject,
final String bjondAdapterAudience,
final String issuer,
final String bjondAdapterAudience,
final String bjondAdapterSubject,
final String json,
final int expirationTimeMinutesInTheFuture) throws JoseException {

Expand Down
194 changes: 194 additions & 0 deletions src/test/java/com/bjond/test/TestJWTUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,28 @@

package com.bjond.test;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.StrictAssertions.assertThat;

import java.security.Key;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.jose4j.base64url.Base64;
import org.jose4j.jwe.ContentEncryptionAlgorithmIdentifiers;
import org.jose4j.jwe.JsonWebEncryption;
import org.jose4j.jwe.KeyManagementAlgorithmIdentifiers;
import org.jose4j.jwt.JwtClaims;
import org.jose4j.jwt.consumer.JwtConsumer;
import org.jose4j.jwt.consumer.JwtConsumerBuilder;
import org.jose4j.keys.AesKey;
import org.jose4j.lang.ByteUtil;
import org.junit.Assert;
import org.junit.Test;

import com.bjond.jwtutils.JWTUtil;

/** JUnit Test Suite TestBrigid
*
* @version 0.001 10/16/15mport scala.ScalaHelloWorld;
Expand All @@ -38,6 +57,181 @@ public void sanityCheck() throws Exception {
System.out.println("This is a test"); // You should see this in the html report in stdout.
}


@Test
public void test_generateJWTToken() throws Exception {
final byte[] keyBytes = JWTUtil.generateRandomKey_AES128();
final Key key = JWTUtil.generateAESKey(keyBytes);

final String issuer = "Bjönd, Inc";
final String audience = "Axis Health";
final String subject = "Adapter Token";

final String token = JWTUtil.generateJWTToken(Base64.encode(keyBytes), issuer, audience, subject, "this is a test", 10);
final JwtClaims claims = JWTUtil.validateTokenAndProcessClaims(key, issuer, audience, subject, 30, token);


assertThat(claims).isNotNull();

final Map<String, List<Object>> claimsMap2 = claims.flattenClaims();
assertThat(claimsMap2).isNotNull();
assertThat(claimsMap2.get("json")).hasSize(1).contains("this is a test");
}

@Test
public void constructionAndVerification_JWE() throws Exception {
final String helloWorld = "Hello World!";

// https://bitbucket.org/b_c/jose4j/wiki/Home
// Basic JWE construction and verification.
final Key key = new AesKey(ByteUtil.randomBytes(16));
JsonWebEncryption jwe = new JsonWebEncryption();
jwe.setPayload(helloWorld);
jwe.setAlgorithmHeaderValue(KeyManagementAlgorithmIdentifiers.A128KW);
jwe.setEncryptionMethodHeaderParameter(ContentEncryptionAlgorithmIdentifiers.AES_128_CBC_HMAC_SHA_256);
jwe.setKey(key);
final String serializedJwe = jwe.getCompactSerialization();


jwe = new JsonWebEncryption();
jwe.setKey(key);
jwe.setCompactSerialization(serializedJwe);


assertThat(jwe.getPayload()).isEqualTo(helloWorld);
}

@Test
public void produceAndConsume_JWE_JWT() throws Exception {

//Create the Claims, which will be the content of the JWT
final JwtClaims claims = new JwtClaims();
claims.setIssuer("Issuer"); // who creates the token and signs it
claims.setAudience("Audience"); // to whom the token is intended to be sent
claims.setExpirationTimeMinutesInTheFuture(10); // time when the token will expire (10 minutes from now)
claims.setGeneratedJwtId(); // a unique identifier for the token
claims.setIssuedAtToNow(); // when the token was issued/created (now)
claims.setNotBeforeMinutesInThePast(2); // time before which the token is not yet valid (2 minutes ago)
claims.setSubject("subject"); // the subject/principal is whom the token is about
claims.setClaim("email","[email protected]"); // additional claims/attributes about the subject can be added
List<String> groups = Arrays.asList("group-one", "other-group", "group-three");
claims.setStringListClaim("groups", groups); // multi-valued claims work too

// JWE construction and insert into JWE thus producing JWE/JWT
final Key key = new AesKey(ByteUtil.randomBytes(16));
JsonWebEncryption jwe = new JsonWebEncryption();
jwe.setPayload(claims.toJson());
jwe.setAlgorithmHeaderValue(KeyManagementAlgorithmIdentifiers.A128KW);
jwe.setEncryptionMethodHeaderParameter(ContentEncryptionAlgorithmIdentifiers.AES_128_CBC_HMAC_SHA_256);
jwe.setKey(key);
final String serializedJWT = jwe.getCompactSerialization();


final JwtConsumer jwtConsumer = new JwtConsumerBuilder()
.setRequireExpirationTime() // the JWT must have an expiration time
.setAllowedClockSkewInSeconds(30) // allow some leeway in validating time based claims to account for clock skew
.setRequireSubject() // the JWT must have a subject claim
.setExpectedIssuer("Issuer") // whom the JWT needs to have been issued by
.setExpectedAudience("Audience") // to whom the JWT is intended for
.setDecryptionKey(key)
.setEnableRequireEncryption()
.setDisableRequireSignature()
.setSkipSignatureVerification()
.build(); // create the JwtConsumer instance

// Validate the JWT and process it to the Claims
final JwtClaims jwtClaims = jwtConsumer.processToClaims(serializedJWT);
System.out.println("JWT validation succeeded! " + jwtClaims);

// If it didn't blow up with an InvalidJwtException we are good!
}



@Test
public void ensure_Base64_AES_256_Key_Works() throws Exception {

//Create the Claims, which will be the content of the JWT
final JwtClaims claims = new JwtClaims();
claims.setIssuer("Issuer"); // who creates the token and signs it
claims.setAudience("Audience"); // to whom the token is intended to be sent
claims.setExpirationTimeMinutesInTheFuture(10); // time when the token will expire (10 minutes from now)
claims.setGeneratedJwtId(); // a unique identifier for the token
claims.setIssuedAtToNow(); // when the token was issued/created (now)
claims.setNotBeforeMinutesInThePast(2); // time before which the token is not yet valid (2 minutes ago)
claims.setSubject("subject"); // the subject/principal is whom the token is about
claims.setClaim("email","[email protected]"); // additional claims/attributes about the subject can be added
List<String> groups = Arrays.asList("group-one", "other-group", "group-three");
claims.setStringListClaim("groups", groups); // multi-valued claims work too

// JWE construction and insert into JWE thus producing JWE/JWT
final byte[] AESKey = ByteUtil.randomBytes(16);

/////////////////////////////////////////////////////////////////////////
// This base64AESKeyString is the Base64 secrete key we will generate //
// and register with the Bjond System //
/////////////////////////////////////////////////////////////////////////
final String base64AESKeyString = Base64.encode(AESKey);
final byte[] AESKeyDecoded = Base64.decode(base64AESKeyString);


final Key key = new AesKey(AESKeyDecoded);
JsonWebEncryption jwe = new JsonWebEncryption();
jwe.setPayload(claims.toJson());
jwe.setAlgorithmHeaderValue(KeyManagementAlgorithmIdentifiers.A128KW);
jwe.setEncryptionMethodHeaderParameter(ContentEncryptionAlgorithmIdentifiers.AES_128_CBC_HMAC_SHA_256);
jwe.setKey(key);
final String serializedJWT = jwe.getCompactSerialization();


final JwtConsumer jwtConsumer = new JwtConsumerBuilder()
.setRequireExpirationTime() // the JWT must have an expiration time
.setAllowedClockSkewInSeconds(30) // allow some leeway in validating time based claims to account for clock skew
.setRequireSubject() // the JWT must have a subject claim
.setExpectedIssuer("Issuer") // whom the JWT needs to have been issued by
.setExpectedAudience("Audience") // to whom the JWT is intended for
.setDecryptionKey(key)
.setEnableRequireEncryption()
.setDisableRequireSignature()
.setSkipSignatureVerification()
.build(); // create the JwtConsumer instance

// Validate the JWT and process it to the Claims
final JwtClaims jwtClaims = jwtConsumer.processToClaims(serializedJWT);
System.out.println("JWT validation succeeded! " + jwtClaims);

// If it didn't blow up with an InvalidJwtException we are good!
}


@Test
public void ensureAESKeyGeneration() throws Exception {
final byte[] AESKey = ByteUtil.randomBytes(16); // 128 Bit
final Key key = new AesKey(AESKey);


final String base64Key = Base64.encode(AESKey);
final byte[] key2 = Base64.decode(base64Key);

assertThat(base64Key).isNotEmpty();
assertThat(Arrays.equals(AESKey, key2));



// Just go through the motions, any exceptions?
JsonWebEncryption jwe = new JsonWebEncryption();
jwe.setPayload("Hello World!");
jwe.setAlgorithmHeaderValue(KeyManagementAlgorithmIdentifiers.A128KW);
jwe.setEncryptionMethodHeaderParameter(ContentEncryptionAlgorithmIdentifiers.AES_128_CBC_HMAC_SHA_256);
jwe.setKey(key);
final String serializedJwe = jwe.getCompactSerialization();
jwe = new JsonWebEncryption();
jwe.setKey(key);
jwe.setCompactSerialization(serializedJwe);



}


}
Expand Down

0 comments on commit 756858f

Please sign in to comment.