Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor signing / encryption for JWT: WIP
- Loading branch information
Showing
10 changed files
with
504 additions
and
197 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
99 changes: 99 additions & 0 deletions
99
pac4j-jwt/src/main/java/org/pac4j/jwt/config/DirectEncryptionConfiguration.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,99 @@ | |||
package org.pac4j.jwt.config; | |||
|
|||
import com.nimbusds.jose.*; | |||
import com.nimbusds.jose.crypto.DirectDecrypter; | |||
import com.nimbusds.jose.crypto.DirectEncrypter; | |||
import com.nimbusds.jwt.EncryptedJWT; | |||
import com.nimbusds.jwt.SignedJWT; | |||
import org.pac4j.core.exception.TechnicalException; | |||
import org.pac4j.core.util.CommonHelper; | |||
import org.pac4j.core.util.InitializableObject; | |||
|
|||
import java.io.UnsupportedEncodingException; | |||
|
|||
/** | |||
* Direct encryption configuration. | |||
* | |||
* @author Jerome Leleu | |||
* @since 1.9.2 | |||
*/ | |||
public class DirectEncryptionConfiguration extends InitializableObject implements EncryptionConfiguration { | |||
|
|||
private String secret; | |||
|
|||
private EncryptionMethod method = EncryptionMethod.A256GCM; | |||
|
|||
public DirectEncryptionConfiguration() {} | |||
|
|||
public DirectEncryptionConfiguration(final String secret) { | |||
this.secret = secret; | |||
} | |||
|
|||
public DirectEncryptionConfiguration(final String secret, final EncryptionMethod method) { | |||
this.secret = secret; | |||
this.method = method; | |||
} | |||
|
|||
@Override | |||
protected void internalInit() { | |||
CommonHelper.assertNotBlank("secret", secret); | |||
CommonHelper.assertNotNull("method", method); | |||
} | |||
|
|||
@Override | |||
public String encrypt(final SignedJWT signedJWT) { | |||
init(); | |||
|
|||
// Create JWE object with signed JWT as payload | |||
final JWEObject jweObject = new JWEObject( | |||
new JWEHeader.Builder(JWEAlgorithm.DIR, this.method).contentType("JWT").build(), | |||
new Payload(signedJWT)); | |||
|
|||
try { | |||
// Perform encryption | |||
jweObject.encrypt(new DirectEncrypter(this.secret.getBytes("UTF-8"))); | |||
} catch (final UnsupportedEncodingException | JOSEException e) { | |||
throw new TechnicalException(e); | |||
} | |||
|
|||
// Serialise to JWE compact form | |||
return jweObject.serialize(); | |||
} | |||
|
|||
@Override | |||
public SignedJWT decrypt(EncryptedJWT encryptedJWT) { | |||
init(); | |||
|
|||
try { | |||
final JWEObject jweObject = encryptedJWT; | |||
jweObject.decrypt(new DirectDecrypter(this.secret.getBytes("UTF-8"))); | |||
|
|||
// Extract payload | |||
return jweObject.getPayload().toSignedJWT(); | |||
|
|||
} catch (final UnsupportedEncodingException | JOSEException e) { | |||
throw new TechnicalException(e); | |||
} | |||
} | |||
|
|||
public String getSecret() { | |||
return secret; | |||
} | |||
|
|||
public void setSecret(String secret) { | |||
this.secret = secret; | |||
} | |||
|
|||
public EncryptionMethod getMethod() { | |||
return method; | |||
} | |||
|
|||
public void setMethod(EncryptionMethod method) { | |||
this.method = method; | |||
} | |||
|
|||
@Override | |||
public String toString() { | |||
return CommonHelper.toString(this.getClass(), "secret", "[protected]", "method", method); | |||
} | |||
} |
83 changes: 83 additions & 0 deletions
83
pac4j-jwt/src/main/java/org/pac4j/jwt/config/ECSigningConfiguration.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,83 @@ | |||
package org.pac4j.jwt.config; | |||
|
|||
import com.nimbusds.jose.JOSEException; | |||
import com.nimbusds.jose.JWSAlgorithm; | |||
import com.nimbusds.jose.JWSHeader; | |||
import com.nimbusds.jose.JWSSigner; | |||
import com.nimbusds.jose.crypto.ECDSASigner; | |||
import com.nimbusds.jwt.JWTClaimsSet; | |||
import com.nimbusds.jwt.SignedJWT; | |||
import org.pac4j.core.exception.TechnicalException; | |||
import org.pac4j.core.util.CommonHelper; | |||
import org.pac4j.core.util.InitializableObject; | |||
|
|||
import java.security.interfaces.ECPrivateKey; | |||
|
|||
/** | |||
* Elliptic curve signing configuration: http://connect2id.com/products/nimbus-jose-jwt/examples/jwt-with-rsa-signature | |||
* | |||
* @author Jerome Leleu | |||
* @since 1.9.2 | |||
*/ | |||
public class ECSigningConfiguration extends InitializableObject implements SigningConfiguration { | |||
|
|||
private ECPrivateKey key; | |||
|
|||
private JWSAlgorithm algorithm = JWSAlgorithm.ES256; | |||
|
|||
public ECSigningConfiguration() {} | |||
|
|||
public ECSigningConfiguration(final ECPrivateKey key) { | |||
this.key = key; | |||
} | |||
|
|||
public ECSigningConfiguration(final ECPrivateKey key, final JWSAlgorithm algorithm) { | |||
this.key = key; | |||
this.algorithm = algorithm; | |||
} | |||
|
|||
@Override | |||
protected void internalInit() { | |||
CommonHelper.assertNotNull("algorithm", algorithm); | |||
CommonHelper.assertNotNull("key", key); | |||
|
|||
if (algorithm != JWSAlgorithm.ES256 && algorithm != JWSAlgorithm.ES384 && algorithm != JWSAlgorithm.ES512) { | |||
throw new TechnicalException("Only the ES256, ES384 and ES512 algorithms are supported for elliptic curve signature"); | |||
} | |||
} | |||
|
|||
@Override | |||
public SignedJWT sign(JWTClaimsSet claims) { | |||
init(); | |||
|
|||
try { | |||
final JWSSigner signer = new ECDSASigner(this.key); | |||
final SignedJWT signedJWT = new SignedJWT(new JWSHeader(algorithm), claims); | |||
signedJWT.sign(signer); | |||
return signedJWT; | |||
} catch (final JOSEException e) { | |||
throw new TechnicalException(e); | |||
} | |||
} | |||
|
|||
public ECPrivateKey getKey() { | |||
return key; | |||
} | |||
|
|||
public void setKey(final ECPrivateKey key) { | |||
this.key = key; | |||
} | |||
|
|||
public JWSAlgorithm getAlgorithm() { | |||
return algorithm; | |||
} | |||
|
|||
public void setAlgorithm(final JWSAlgorithm algorithm) { | |||
this.algorithm = algorithm; | |||
} | |||
|
|||
@Override | |||
public String toString() { | |||
return CommonHelper.toString(this.getClass(), "key", "[protected]", "algorithm", algorithm); | |||
} | |||
} |
29 changes: 29 additions & 0 deletions
29
pac4j-jwt/src/main/java/org/pac4j/jwt/config/EncryptionConfiguration.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,29 @@ | |||
package org.pac4j.jwt.config; | |||
|
|||
import com.nimbusds.jwt.EncryptedJWT; | |||
import com.nimbusds.jwt.SignedJWT; | |||
|
|||
/** | |||
* Encryption configuration. | |||
* | |||
* @author Jerome Leleu | |||
* @since 1.9.2 | |||
*/ | |||
public interface EncryptionConfiguration { | |||
|
|||
/** | |||
* Encrypt a signed JWT. | |||
* | |||
* @param signedJWT the signed JWT | |||
* @return the encrypted signed JWT | |||
*/ | |||
String encrypt(SignedJWT signedJWT); | |||
|
|||
/** | |||
* Decrypt an encrypted (signed) JWT. | |||
* | |||
* @param encryptedJWT the encrypted JWT | |||
* @return the decrypted (signed) JWT | |||
*/ | |||
SignedJWT decrypt(EncryptedJWT encryptedJWT); | |||
} |
78 changes: 78 additions & 0 deletions
78
pac4j-jwt/src/main/java/org/pac4j/jwt/config/MacSigningConfiguration.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,78 @@ | |||
package org.pac4j.jwt.config; | |||
|
|||
import com.nimbusds.jose.*; | |||
import com.nimbusds.jose.crypto.MACSigner; | |||
import com.nimbusds.jwt.JWTClaimsSet; | |||
import com.nimbusds.jwt.SignedJWT; | |||
import org.pac4j.core.exception.TechnicalException; | |||
import org.pac4j.core.util.CommonHelper; | |||
import org.pac4j.core.util.InitializableObject; | |||
|
|||
/** | |||
* HMac signing configuration: http://connect2id.com/products/nimbus-jose-jwt/examples/jwt-with-hmac | |||
* | |||
* @author Jerome Leleu | |||
* @since 1.9.2 | |||
*/ | |||
public class MacSigningConfiguration extends InitializableObject implements SigningConfiguration { | |||
|
|||
private String secret; | |||
|
|||
private JWSAlgorithm algorithm = JWSAlgorithm.HS256; | |||
|
|||
public MacSigningConfiguration() {} | |||
|
|||
public MacSigningConfiguration(final String secret) { | |||
this.secret = secret; | |||
} | |||
|
|||
public MacSigningConfiguration(final String secret, final JWSAlgorithm algorithm) { | |||
this.secret = secret; | |||
this.algorithm = algorithm; | |||
} | |||
|
|||
@Override | |||
protected void internalInit() { | |||
CommonHelper.assertNotNull("algorithm", algorithm); | |||
CommonHelper.assertNotBlank("secret", secret); | |||
|
|||
if (algorithm != JWSAlgorithm.HS256 && algorithm != JWSAlgorithm.HS384 && algorithm != JWSAlgorithm.HS512) { | |||
throw new TechnicalException("Only the HS256, HS384 and HS512 algorithms are supported for HMac signature"); | |||
} | |||
} | |||
|
|||
@Override | |||
public SignedJWT sign(JWTClaimsSet claims) { | |||
init(); | |||
|
|||
try { | |||
final JWSSigner signer = new MACSigner(this.secret); | |||
final SignedJWT signedJWT = new SignedJWT(new JWSHeader(algorithm), claims); | |||
signedJWT.sign(signer); | |||
return signedJWT; | |||
} catch (final JOSEException e) { | |||
throw new TechnicalException(e); | |||
} | |||
} | |||
|
|||
public String getSecret() { | |||
return secret; | |||
} | |||
|
|||
public void setSecret(final String secret) { | |||
this.secret = secret; | |||
} | |||
|
|||
public JWSAlgorithm getAlgorithm() { | |||
return algorithm; | |||
} | |||
|
|||
public void setAlgorithm(final JWSAlgorithm algorithm) { | |||
this.algorithm = algorithm; | |||
} | |||
|
|||
@Override | |||
public String toString() { | |||
return CommonHelper.toString(this.getClass(), "secret", "[protected]", "algorithm", algorithm); | |||
} | |||
} |
84 changes: 84 additions & 0 deletions
84
pac4j-jwt/src/main/java/org/pac4j/jwt/config/RSASigningConfiguration.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,84 @@ | |||
package org.pac4j.jwt.config; | |||
|
|||
import com.nimbusds.jose.JOSEException; | |||
import com.nimbusds.jose.JWSAlgorithm; | |||
import com.nimbusds.jose.JWSHeader; | |||
import com.nimbusds.jose.JWSSigner; | |||
import com.nimbusds.jose.crypto.RSASSASigner; | |||
import com.nimbusds.jwt.JWTClaimsSet; | |||
import com.nimbusds.jwt.SignedJWT; | |||
import org.pac4j.core.exception.TechnicalException; | |||
import org.pac4j.core.util.CommonHelper; | |||
import org.pac4j.core.util.InitializableObject; | |||
|
|||
import java.security.interfaces.RSAPrivateKey; | |||
|
|||
/** | |||
* RSA signing configuration: http://connect2id.com/products/nimbus-jose-jwt/examples/jwt-with-rsa-signature | |||
* | |||
* @author Jerome Leleu | |||
* @since 1.9.2 | |||
*/ | |||
public class RSASigningConfiguration extends InitializableObject implements SigningConfiguration { | |||
|
|||
private RSAPrivateKey key; | |||
|
|||
private JWSAlgorithm algorithm = JWSAlgorithm.RS256; | |||
|
|||
public RSASigningConfiguration() {} | |||
|
|||
public RSASigningConfiguration(final RSAPrivateKey key) { | |||
this.key = key; | |||
} | |||
|
|||
public RSASigningConfiguration(final RSAPrivateKey key, final JWSAlgorithm algorithm) { | |||
this.key = key; | |||
this.algorithm = algorithm; | |||
} | |||
|
|||
@Override | |||
protected void internalInit() { | |||
CommonHelper.assertNotNull("algorithm", algorithm); | |||
CommonHelper.assertNotNull("key", key); | |||
|
|||
if (algorithm != JWSAlgorithm.RS256 && algorithm != JWSAlgorithm.RS384 && algorithm != JWSAlgorithm.RS512 && | |||
algorithm != JWSAlgorithm.PS256 && algorithm != JWSAlgorithm.PS384 && algorithm != JWSAlgorithm.PS512) { | |||
throw new TechnicalException("Only the RS256, RS384, RS512, PS256, PS384 and PS512 algorithms are supported for RSA signature"); | |||
} | |||
} | |||
|
|||
@Override | |||
public SignedJWT sign(JWTClaimsSet claims) { | |||
init(); | |||
|
|||
try { | |||
final JWSSigner signer = new RSASSASigner(this.key); | |||
final SignedJWT signedJWT = new SignedJWT(new JWSHeader(algorithm), claims); | |||
signedJWT.sign(signer); | |||
return signedJWT; | |||
} catch (final JOSEException e) { | |||
throw new TechnicalException(e); | |||
} | |||
} | |||
|
|||
public RSAPrivateKey getKey() { | |||
return key; | |||
} | |||
|
|||
public void setKey(final RSAPrivateKey key) { | |||
this.key = key; | |||
} | |||
|
|||
public JWSAlgorithm getAlgorithm() { | |||
return algorithm; | |||
} | |||
|
|||
public void setAlgorithm(final JWSAlgorithm algorithm) { | |||
this.algorithm = algorithm; | |||
} | |||
|
|||
@Override | |||
public String toString() { | |||
return CommonHelper.toString(this.getClass(), "key", "[protected]", "algorithm", algorithm); | |||
} | |||
} |
Oops, something went wrong.