You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by dr...@apache.org on 2015/03/30 06:48:32 UTC
[2/2] directory-kerby git commit: DIRKRB-194 Token signature
verification. Contributed by Jiajia
DIRKRB-194 Token signature verification. Contributed by Jiajia
Project: http://git-wip-us.apache.org/repos/asf/directory-kerby/repo
Commit: http://git-wip-us.apache.org/repos/asf/directory-kerby/commit/9f2fe83c
Tree: http://git-wip-us.apache.org/repos/asf/directory-kerby/tree/9f2fe83c
Diff: http://git-wip-us.apache.org/repos/asf/directory-kerby/diff/9f2fe83c
Branch: refs/heads/master
Commit: 9f2fe83c1f8e6c294c095dfb6e10af43ec450cea
Parents: d0f33b0
Author: Drankye <dr...@gmail.com>
Authored: Mon Mar 30 20:45:42 2015 +0800
Committer: Drankye <dr...@gmail.com>
Committed: Mon Mar 30 20:45:42 2015 +0800
----------------------------------------------------------------------
.../provider/token/JwtTokenDecoder.java | 64 ++++++++++++++++++--
.../provider/token/JwtTokenEncoder.java | 51 +++++++++++++++-
.../kerberos/provider/token/TokenTest.java | 37 +++++++++++
3 files changed, 146 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9f2fe83c/kerby-provider/token-provider/src/main/java/org/apache/kerby/kerberos/provider/token/JwtTokenDecoder.java
----------------------------------------------------------------------
diff --git a/kerby-provider/token-provider/src/main/java/org/apache/kerby/kerberos/provider/token/JwtTokenDecoder.java b/kerby-provider/token-provider/src/main/java/org/apache/kerby/kerberos/provider/token/JwtTokenDecoder.java
index c915ae1..d662dff 100644
--- a/kerby-provider/token-provider/src/main/java/org/apache/kerby/kerberos/provider/token/JwtTokenDecoder.java
+++ b/kerby-provider/token-provider/src/main/java/org/apache/kerby/kerberos/provider/token/JwtTokenDecoder.java
@@ -20,16 +20,20 @@
package org.apache.kerby.kerberos.provider.token;
import com.nimbusds.jose.JOSEException;
+import com.nimbusds.jose.JWSVerifier;
import com.nimbusds.jose.crypto.RSADecrypter;
+import com.nimbusds.jose.crypto.RSASSAVerifier;
import com.nimbusds.jwt.EncryptedJWT;
import com.nimbusds.jwt.JWT;
import com.nimbusds.jwt.JWTParser;
import com.nimbusds.jwt.PlainJWT;
+import com.nimbusds.jwt.SignedJWT;
import org.apache.kerby.kerberos.kerb.provider.TokenDecoder;
import org.apache.kerby.kerberos.kerb.spec.base.AuthToken;
import java.io.IOException;
import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
import java.text.ParseException;
/**
@@ -37,6 +41,7 @@ import java.text.ParseException;
*/
public class JwtTokenDecoder implements TokenDecoder {
private static RSAPrivateKey decryptionKey;
+ private static RSAPublicKey verifyKey;
@Override
public AuthToken decodeFromBytes(byte[] content) throws IOException {
@@ -65,10 +70,36 @@ public class JwtTokenDecoder implements TokenDecoder {
} else if (jwt instanceof EncryptedJWT) {
EncryptedJWT encryptedJWT = (EncryptedJWT) jwt;
decryptEncryptedJWT(encryptedJWT);
- try {
- return new JwtAuthToken(encryptedJWT.getJWTClaimsSet());
- } catch (ParseException e) {
- throw new IOException("Failed to get JWT claims set", e);
+ SignedJWT signedJWT = encryptedJWT.getPayload().toSignedJWT();
+ if (signedJWT != null) {
+ boolean success = verifySignedJWT(signedJWT);
+ if (success) {
+ try {
+ return new JwtAuthToken(signedJWT.getJWTClaimsSet());
+ } catch (ParseException e) {
+ throw new IOException("Failed to get JWT claims set", e);
+ }
+ } else {
+ return null;
+ }
+ } else {
+ try {
+ return new JwtAuthToken(encryptedJWT.getJWTClaimsSet());
+ } catch (ParseException e) {
+ throw new IOException("Failed to get JWT claims set", e);
+ }
+ }
+ } else if (jwt instanceof SignedJWT) {
+ SignedJWT signedJWT = (SignedJWT) jwt;
+ boolean success = verifySignedJWT(signedJWT);
+ if (success) {
+ try {
+ return new JwtAuthToken(signedJWT.getJWTClaimsSet());
+ } catch (ParseException e) {
+ throw new IOException("Failed to get JWT claims set", e);
+ }
+ } else {
+ return null;
}
} else {
throw new IOException("Unexpected JWT type: " + jwt);
@@ -97,4 +128,29 @@ public class JwtTokenDecoder implements TokenDecoder {
public static void setDecryptionKey(RSAPrivateKey key) {
decryptionKey = key;
}
+
+ /**
+ * verify the Signed JWT
+ *
+ * @param signedJWT
+ * @return whether verify success
+ */
+ public boolean verifySignedJWT(SignedJWT signedJWT) throws IOException {
+ JWSVerifier verifier = new RSASSAVerifier(verifyKey);
+ try {
+ return signedJWT.verify(verifier);
+ } catch (JOSEException e) {
+ throw new IOException("Failed to verify the signed JWT", e);
+ }
+ }
+
+ /**
+ * set the verify key
+ *
+ * @param key a public key
+ */
+ public static void setVerifyKey(RSAPublicKey key) {
+ verifyKey = key;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9f2fe83c/kerby-provider/token-provider/src/main/java/org/apache/kerby/kerberos/provider/token/JwtTokenEncoder.java
----------------------------------------------------------------------
diff --git a/kerby-provider/token-provider/src/main/java/org/apache/kerby/kerberos/provider/token/JwtTokenEncoder.java b/kerby-provider/token-provider/src/main/java/org/apache/kerby/kerberos/provider/token/JwtTokenEncoder.java
index 07b5c3e..69668f6 100644
--- a/kerby-provider/token-provider/src/main/java/org/apache/kerby/kerberos/provider/token/JwtTokenEncoder.java
+++ b/kerby-provider/token-provider/src/main/java/org/apache/kerby/kerberos/provider/token/JwtTokenEncoder.java
@@ -23,13 +23,21 @@ import com.nimbusds.jose.EncryptionMethod;
import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JWEAlgorithm;
import com.nimbusds.jose.JWEHeader;
+import com.nimbusds.jose.JWEObject;
+import com.nimbusds.jose.JWSAlgorithm;
+import com.nimbusds.jose.JWSHeader;
+import com.nimbusds.jose.JWSSigner;
+import com.nimbusds.jose.Payload;
import com.nimbusds.jose.crypto.RSAEncrypter;
+import com.nimbusds.jose.crypto.RSASSASigner;
import com.nimbusds.jwt.EncryptedJWT;
import com.nimbusds.jwt.JWT;
+import com.nimbusds.jwt.SignedJWT;
import org.apache.kerby.kerberos.kerb.KrbException;
import org.apache.kerby.kerberos.kerb.provider.TokenEncoder;
import org.apache.kerby.kerberos.kerb.spec.base.AuthToken;
+import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.text.ParseException;
@@ -40,6 +48,8 @@ public class JwtTokenEncoder implements TokenEncoder {
private static JWEAlgorithm jweAlgorithm = JWEAlgorithm.RSA_OAEP;
private static EncryptionMethod encryptionMethod = EncryptionMethod.A128GCM;
private static RSAPublicKey encryptionKey;
+ private static JWSAlgorithm jwsAlgorithm = JWSAlgorithm.RS256;
+ private static RSAPrivateKey signKey;
@Override
public byte[] encodeAsBytes(AuthToken token) throws KrbException {
@@ -57,8 +67,36 @@ public class JwtTokenEncoder implements TokenEncoder {
JWT jwt = jwtAuthToken.getJwt();
String tokenStr = null;
- // Encrypt
- if (encryptionKey != null) {
+ if (signKey != null) {
+ // Create signer with the private key
+ JWSSigner signer = new RSASSASigner(signKey);
+ SignedJWT signedJWT = null;
+ try {
+ signedJWT = new SignedJWT(new JWSHeader(jwsAlgorithm), jwt.getJWTClaimsSet());
+ } catch (ParseException e) {
+ throw new KrbException("Failed to get JWT claims set", e);
+ }
+ try {
+ signedJWT.sign(signer);
+ } catch (JOSEException e) {
+ throw new KrbException("Failed to sign the Signed JWT", e);
+ }
+ // Encrypt
+ if (encryptionKey != null) {
+ // Create JWE object with signedJWT as payload
+ JWEObject jweObject = new JWEObject(
+ new JWEHeader.Builder(jweAlgorithm, encryptionMethod).contentType("JWT").build(),
+ new Payload(signedJWT));
+ try {
+ jweObject.encrypt(new RSAEncrypter(encryptionKey));
+ } catch (JOSEException e) {
+ throw new KrbException("Failed to encrypt the JWE object", e);
+ }
+ tokenStr = jweObject.serialize();
+ } else {
+ tokenStr = signedJWT.serialize();
+ }
+ } else if (encryptionKey != null) {
JWEHeader header = new JWEHeader(jweAlgorithm, encryptionMethod);
EncryptedJWT encryptedJWT = null;
try {
@@ -87,4 +125,13 @@ public class JwtTokenEncoder implements TokenEncoder {
public static void setEncryptionKey(RSAPublicKey key) {
encryptionKey = key;
}
+
+ /**
+ * set the sign key
+ *
+ * @param key a private key
+ */
+ public static void setSignKey(RSAPrivateKey key) {
+ signKey = key;
+ }
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9f2fe83c/kerby-provider/token-provider/src/test/java/org/apache/kerby/kerberos/provider/token/TokenTest.java
----------------------------------------------------------------------
diff --git a/kerby-provider/token-provider/src/test/java/org/apache/kerby/kerberos/provider/token/TokenTest.java b/kerby-provider/token-provider/src/test/java/org/apache/kerby/kerberos/provider/token/TokenTest.java
index da5422b..2baa3be 100644
--- a/kerby-provider/token-provider/src/test/java/org/apache/kerby/kerberos/provider/token/TokenTest.java
+++ b/kerby-provider/token-provider/src/test/java/org/apache/kerby/kerberos/provider/token/TokenTest.java
@@ -105,6 +105,37 @@ public class TokenTest {
Assertions.assertThat(token2.getIssuer()).isEqualTo(ISSUER);
}
+ @Test
+ public void testTokenWithSignedJWT() throws Exception {
+ setSignKey();
+ TokenEncoder tokenEncoder = KrbRuntime.getTokenProvider().createTokenEncoder();
+ String tokenStr = tokenEncoder.encodeAsString(authToken);
+ System.out.println("Auth token: " + tokenStr);
+ Assertions.assertThat(tokenStr).isNotNull();
+
+ TokenDecoder tokenDecoder = KrbRuntime.getTokenProvider().createTokenDecoder();
+ AuthToken token2 = tokenDecoder.decodeFromString(tokenStr);
+ System.out.println("Decoded token's subject: " + token2.getSubject());
+ Assertions.assertThat(token2.getSubject()).isEqualTo(SUBJECT);
+ Assertions.assertThat(token2.getIssuer()).isEqualTo(ISSUER);
+ }
+
+ @Test
+ public void testTokenWithSingedAndEncryptedJWT() throws Exception {
+ setSignKey();
+ setEncryptKey();
+ TokenEncoder tokenEncoder = KrbRuntime.getTokenProvider().createTokenEncoder();
+ String tokenStr = tokenEncoder.encodeAsString(authToken);
+ System.out.println("Auth token: " + tokenStr);
+ Assertions.assertThat(tokenStr).isNotNull();
+
+ TokenDecoder tokenDecoder = KrbRuntime.getTokenProvider().createTokenDecoder();
+ AuthToken token2 = tokenDecoder.decodeFromString(tokenStr);
+ System.out.println("Decoded token's subject: " + token2.getSubject());
+ Assertions.assertThat(token2.getSubject()).isEqualTo(SUBJECT);
+ Assertions.assertThat(token2.getIssuer()).isEqualTo(ISSUER);
+ }
+
private void setEncryptKey() {
KeyPair encryptionKeyPair = getKeyPair();
JwtTokenEncoder.setEncryptionKey((RSAPublicKey) encryptionKeyPair.getPublic());
@@ -120,4 +151,10 @@ public class TokenTest {
}
return kpg.generateKeyPair();
}
+
+ private void setSignKey() {
+ KeyPair signKeyPair = getKeyPair();
+ JwtTokenEncoder.setSignKey((RSAPrivateKey) signKeyPair.getPrivate());
+ JwtTokenDecoder.setVerifyKey((RSAPublicKey)signKeyPair.getPublic());
+ }
}