Skip to content

Commit

Permalink
test cxf, nimbus compability
Browse files Browse the repository at this point in the history
Signed-off-by: Maciej Mierzwa <[email protected]>
  • Loading branch information
MaciejMierzwa committed Oct 23, 2023
1 parent eb45337 commit dd02d0c
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 2 deletions.
4 changes: 4 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,10 @@ dependencies {
implementation "io.jsonwebtoken:jjwt-api:${jjwt_version}"
implementation "io.jsonwebtoken:jjwt-impl:${jjwt_version}"
implementation "io.jsonwebtoken:jjwt-jackson:${jjwt_version}"
implementation("org.apache.cxf:cxf-rt-rs-security-jose:${apache_cxf_version}") {
exclude(group: 'jakarta.activation', module: 'jakarta.activation-api')
}

// JSON flattener
implementation ("com.github.wnameless.json:json-base:2.4.3") {
exclude group: "org.glassfish", module: "jakarta.json"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ static Tuple<JWK, JWSSigner> createJwkFromSettings(Settings settings) {
String paddedSecret = padSecret(new String(decoded), JWSAlgorithm.HS512);

key = new OctetSequenceKey.Builder(paddedSecret.getBytes(StandardCharsets.UTF_8)).algorithm(JWSAlgorithm.HS512)
.keyUse(KeyUse.SIGNATURE)
.build();
.keyUse(KeyUse.SIGNATURE)
.build();
}

try {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.security.authtoken.jwt;

import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jose.JWSVerifier;
import com.nimbusds.jose.crypto.MACVerifier;
import com.nimbusds.jose.crypto.factories.DefaultJWSSignerFactory;
import com.nimbusds.jose.jwk.OctetSequenceKey;
import com.nimbusds.jose.util.Base64URL;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;
import org.apache.commons.lang3.StringUtils;
import org.apache.cxf.rs.security.jose.jwa.SignatureAlgorithm;
import org.apache.cxf.rs.security.jose.jwe.JweDecryptionProvider;
import org.apache.cxf.rs.security.jose.jwe.JweEncryptionProvider;
import org.apache.cxf.rs.security.jose.jws.HmacJwsSignatureProvider;
import org.apache.cxf.rs.security.jose.jws.HmacJwsSignatureVerifier;
import org.apache.cxf.rs.security.jose.jws.JwsSignatureProvider;
import org.apache.cxf.rs.security.jose.jws.JwsSignatureVerifier;
import org.apache.cxf.rs.security.jose.jwt.JoseJwtConsumer;
import org.apache.cxf.rs.security.jose.jwt.JwtClaims;
import org.apache.cxf.rs.security.jose.jwt.JwtToken;
import org.junit.Assert;
import org.junit.Test;

import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.util.Base64;
import java.util.Date;

import org.apache.cxf.rs.security.jose.jwt.JoseJwtProducer;

public class CxfNimbusCompabilityTest {

@Test
public void testGenerateCXFJwtValidateUsingNimbus() throws Exception {
// raw classes without projects JWTVendor wrapper class
// cxf
String shortSecret = "someShortSecret1";
cxfToNimbusJwtVerification(shortSecret);
// perfectLength
String sixFourBytesSecret = "someSixFourBytesSecretsomeSixFourBytesSecretsomeSixFourBytesSecr";
cxfToNimbusJwtVerification(sixFourBytesSecret);
// longer
String longSecret =
"someReallyLongSecretsomeReallyLongSecretsomeReallyLongSecretsomeReallyLongSecretsomeReallyLongSecretsomeReallyLongSecret";
cxfToNimbusJwtVerification(longSecret);
}

private static void cxfToNimbusJwtVerification(String someSecret) throws ParseException, JOSEException {
String base64EncodedSecret = Base64.getEncoder().encodeToString(someSecret.getBytes(StandardCharsets.UTF_8));

// claims
JwtClaims claims = new JwtClaims();
claims.setIssuedAt(100L);
claims.setIssuer("cluster_0");
// token
JwtToken jwtToken = new JwtToken(claims);

JwsSignatureProvider jwsSignatureProvider = new HmacJwsSignatureProvider(base64EncodedSecret, SignatureAlgorithm.HS512);
JweEncryptionProvider jweEncryptionProvider = null;

JoseJwtProducer producer = new JoseJwtProducer();
String encodedCxfJwt = producer.processJwt(jwtToken, jweEncryptionProvider, jwsSignatureProvider);

// parse using nimbus lib
SignedJWT signedJWT = SignedJWT.parse(encodedCxfJwt);
// nimbus verifier
JWSVerifier verifier = new MACVerifier(StringUtils.rightPad(someSecret, 64, "\0"));

Assert.assertTrue(signedJWT.verify(verifier));
}

@Test
public void testGenerateNimbusJwtValidateUsingCxf() throws Exception {
// raw classes without projects JWTVendor wrapper class
// nimbus
String shortSecret = "someShortSecret";
nimbusToCxfJwtVerification(shortSecret);
// perfectLength
String sixFourBytesSecret = "someSixFourBytesSecretsomeSixFourBytesSecretsomeSixFourBytesSecr";
nimbusToCxfJwtVerification(sixFourBytesSecret);
// longer
String longSecret =
"someReallyLongSecretsomeReallyLongSecretsomeReallyLongSecretsomeReallyLongSecretsomeReallyLongSecretsomeReallyLongSecret";
nimbusToCxfJwtVerification(longSecret);
}

private static void nimbusToCxfJwtVerification(String secret) throws JOSEException {
String base64EncodedSecret = Base64.getEncoder()
.encodeToString(StringUtils.rightPad(secret, 64, "\0").getBytes(StandardCharsets.UTF_8));

// claims
JWSHeader header = new JWSHeader.Builder(JWSAlgorithm.HS512).build();
JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().issuer("cluster_0").issueTime(new Date(100L)).build();

SignedJWT signedJWT = new SignedJWT(header, claimsSet);
// nimbus signer
Base64URL base64URL = new Base64URL(base64EncodedSecret);
OctetSequenceKey key = new OctetSequenceKey.Builder(Base64.getDecoder().decode(base64EncodedSecret)).build();
signedJWT.sign(new DefaultJWSSignerFactory().createJWSSigner(key));

String encodedNimbusJwt = signedJWT.serialize();

// parse using cxf lib and validate signature
JweDecryptionProvider theDecryptor = null;
// no padding at this point
JwsSignatureVerifier theSigVerifier = new HmacJwsSignatureVerifier(
Base64.getEncoder().encodeToString(secret.getBytes(StandardCharsets.UTF_8)),
SignatureAlgorithm.HS512
);
// padding added, shouldn't matter
JwsSignatureVerifier theSigVerifierPadded = new HmacJwsSignatureVerifier(base64EncodedSecret, SignatureAlgorithm.HS512);

// signature validation inside
new JoseJwtConsumer().getJwtToken(encodedNimbusJwt, theDecryptor, theSigVerifier);
new JoseJwtConsumer().getJwtToken(encodedNimbusJwt, theDecryptor, theSigVerifierPadded);
}

}

0 comments on commit dd02d0c

Please sign in to comment.