Skip to content

Commit

Permalink
Added a test for PEM.. tricky one.. it lead to a little refactor of
Browse files Browse the repository at this point in the history
JwtGenerator
  • Loading branch information
Garry committed Jun 3, 2016
1 parent 7063591 commit b5dd73b
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 4 deletions.
Expand Up @@ -212,7 +212,7 @@ public void setSigningPem(final String publicKeyPEM, final String algorithm) thr
// from http://stackoverflow.com/questions/35739932/how-do-i-decode-a-jwt-token-using-an-rsa-public-key-in-pem-format
// decode to its constituent bytes
String publicKeyPEMToUse = publicKeyPEM;
publicKeyPEMToUse = publicKeyPEMToUse.replace("-----BEGIN PUBLIC KEY-----\n", "");
publicKeyPEMToUse = publicKeyPEMToUse.replaceAll("-----BEGIN PUBLIC KEY-----[\\r\\n]+", "");
publicKeyPEMToUse = publicKeyPEMToUse.replace("-----END PUBLIC KEY-----", "");
byte[] publicKeyBytes = javax.xml.bind.DatatypeConverter.parseBase64Binary(publicKeyPEMToUse);

Expand Down
26 changes: 23 additions & 3 deletions pac4j-jwt/src/main/java/org/pac4j/jwt/profile/JwtGenerator.java
Expand Up @@ -67,22 +67,38 @@ public JwtGenerator(final String signingSecret, final String encryptionSecret) {
this.signingSecret = signingSecret;
this.encryptionSecret = encryptionSecret;
}

/**
* Generates a JWT from a user profile.
*
* @param profile the given user profile
* @return the created JWT
*/
public String generate(final U profile) {
try {
// Create HMAC signer
final JWSSigner signer = new MACSigner(this.signingSecret);
return generate(profile, signer, this.jwsAlgorithm);
} catch (JOSEException e) {
throw new RuntimeException(e);
}
}

/**
* Generates a JWT from a user profile.
*
* @param profile the given user profile
* @return the created JWT
*/
public String generate(final U profile, JWSSigner signer, JWSAlgorithm jwsAlgorithm) {
verifyProfile(profile);

try {
final JWTClaimsSet claims = buildJwtClaimsSet(profile);
if (CommonHelper.isNotBlank(this.signingSecret)) {
CommonHelper.assertNotNull("jwsAlgorithm", this.jwsAlgorithm);
CommonHelper.assertNotNull("jwsAlgorithm", jwsAlgorithm);

final SignedJWT signedJWT = signJwt(claims);
final SignedJWT signedJWT = signJwt(claims, signer, jwsAlgorithm);

if (CommonHelper.isNotBlank(this.encryptionSecret)) {
CommonHelper.assertNotNull("jweAlgorithm", jweAlgorithm);
Expand Down Expand Up @@ -116,6 +132,10 @@ protected String encryptJwt(final SignedJWT signedJWT) throws Exception {
protected SignedJWT signJwt(final JWTClaimsSet claims) throws JOSEException {
// Create HMAC signer
final JWSSigner signer = new MACSigner(this.signingSecret);
return signJwt(claims, signer, this.jwsAlgorithm);
}

protected SignedJWT signJwt(final JWTClaimsSet claims, JWSSigner signer, JWSAlgorithm jwsAlgorithm) throws JOSEException {
final SignedJWT signedJWT = new SignedJWT(new JWSHeader(jwsAlgorithm), claims);
// Apply the HMAC
signedJWT.sign(signer);
Expand Down
59 changes: 59 additions & 0 deletions pac4j-jwt/src/test/java/org/pac4j/jwt/JwtTests.java
@@ -1,5 +1,8 @@
package org.pac4j.jwt;

import org.bouncycastle.jce.provider.PEMUtil;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemWriter;
import org.junit.Test;
import org.pac4j.core.exception.HttpAction;
import org.pac4j.core.exception.TechnicalException;
Expand All @@ -12,6 +15,22 @@
import org.pac4j.oauth.profile.facebook.FacebookAttributesDefinition;
import org.pac4j.oauth.profile.facebook.FacebookProfile;

import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.crypto.ECDSASigner;
import com.nimbusds.jose.jwk.ECKey;

import java.io.IOException;
import java.io.StringWriter;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.ECFieldFp;
import java.security.spec.ECParameterSpec;
import java.security.spec.ECPoint;
import java.security.spec.EllipticCurve;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
Expand Down Expand Up @@ -69,6 +88,46 @@ public void testPlainJwt() throws HttpAction {
final String token = generator.generate(profile);
assertToken(profile, token);
}

@Test
public void testPemJwt() throws Exception {
final JwtGenerator<FacebookProfile> generator = new JwtGenerator<>(null, null);
final FacebookProfile profile = createProfile();
KeyPair keyPair = createECKeyPair(EC256SPEC);

ECPublicKey publicKey = (ECPublicKey) keyPair.getPublic();
ECPrivateKey privateKey = (ECPrivateKey) keyPair.getPrivate();
final String token = generator.generate(profile, new ECDSASigner(privateKey), JWSAlgorithm.ES256);
assertToken(profile, token, new JwtAuthenticator(getPem("PUBLIC KEY", publicKey.getEncoded()), "EC", null));
}
private static final int COFACTOR = 1;
private static final ECParameterSpec EC256SPEC = new ECParameterSpec(
new EllipticCurve(
new ECFieldFp(new BigInteger("115792089210356248762697446949407573530086143415290314195533631308867097853951")),
new BigInteger("115792089210356248762697446949407573530086143415290314195533631308867097853948"),
new BigInteger("41058363725152142129326129780047268409114441015993725554835256314039467401291")),
new ECPoint(
new BigInteger("48439561293906451759052585252797914202762949526041747995844080717082404635286"),
new BigInteger("36134250956749795798585127919587881956611106672985015071877198253568414405109")),
new BigInteger("115792089210356248762697446949407573529996955224135760342422259061068512044369"),
COFACTOR);

private static KeyPair createECKeyPair(final AlgorithmParameterSpec spec)
throws Exception {

// Create the public and private keys
KeyPairGenerator keyGenerator = KeyPairGenerator.getInstance("EC");
keyGenerator.initialize(spec);
return keyGenerator.generateKeyPair();
}
private String getPem(String keyTitle, byte[] encodedKey) throws IOException {
StringWriter writer = new StringWriter();
PemWriter pemWriter = new PemWriter(writer);
pemWriter.writeObject(new PemObject("PUBLIC KEY", encodedKey));
pemWriter.flush();
pemWriter.close();
return writer.toString();
}

@Test
public void testGenerateAuthenticate() throws HttpAction {
Expand Down

0 comments on commit b5dd73b

Please sign in to comment.