KEYCLOAK-19510 Nested JWT JOSE header needs to set JWT to cty field
This commit is contained in:
parent
675e1b0941
commit
a4f83c569d
4 changed files with 45 additions and 1 deletions
|
@ -67,6 +67,14 @@ public class JWEHeader implements JOSEHeader {
|
|||
this.keyId = keyId;
|
||||
}
|
||||
|
||||
public JWEHeader(String algorithm, String encryptionAlgorithm, String compressionAlgorithm, String keyId, String contentType) {
|
||||
this.algorithm = algorithm;
|
||||
this.encryptionAlgorithm = encryptionAlgorithm;
|
||||
this.compressionAlgorithm = compressionAlgorithm;
|
||||
this.keyId = keyId;
|
||||
this.contentType = contentType;
|
||||
}
|
||||
|
||||
public String getAlgorithm() {
|
||||
return algorithm;
|
||||
}
|
||||
|
|
|
@ -154,7 +154,7 @@ public class TokenUtil {
|
|||
}
|
||||
|
||||
public static String jweKeyEncryptionEncode(Key encryptionKEK, byte[] contentBytes, String algAlgorithm, String encAlgorithm, String kid, JWEAlgorithmProvider jweAlgorithmProvider, JWEEncryptionProvider jweEncryptionProvider) throws JWEException {
|
||||
JWEHeader jweHeader = new JWEHeader(algAlgorithm, encAlgorithm, null, kid);
|
||||
JWEHeader jweHeader = new JWEHeader(algAlgorithm, encAlgorithm, null, kid, "JWT");
|
||||
return jweKeyEncryptionEncode(encryptionKEK, contentBytes, jweHeader, jweAlgorithmProvider, jweEncryptionProvider);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,13 +20,16 @@ import org.jboss.arquillian.graphene.page.Page;
|
|||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.admin.client.resource.ClientResource;
|
||||
import org.keycloak.common.util.Base64Url;
|
||||
import org.keycloak.common.util.PemUtils;
|
||||
import org.keycloak.crypto.AesCbcHmacShaContentEncryptionProvider;
|
||||
import org.keycloak.crypto.AesGcmContentEncryptionProvider;
|
||||
import org.keycloak.crypto.Algorithm;
|
||||
import org.keycloak.crypto.RsaCekManagementProvider;
|
||||
import org.keycloak.jose.JOSEHeader;
|
||||
import org.keycloak.jose.jwe.JWEConstants;
|
||||
import org.keycloak.jose.jwe.JWEException;
|
||||
import org.keycloak.jose.jwe.JWEHeader;
|
||||
import org.keycloak.jose.jwe.alg.JWEAlgorithmProvider;
|
||||
import org.keycloak.jose.jwe.enc.JWEEncryptionProvider;
|
||||
import org.keycloak.protocol.oidc.OIDCAdvancedConfigWrapper;
|
||||
|
@ -43,8 +46,10 @@ import org.keycloak.testsuite.client.resources.TestOIDCEndpointsApplicationResou
|
|||
import org.keycloak.testsuite.pages.*;
|
||||
import org.keycloak.testsuite.util.OAuthClient;
|
||||
import org.keycloak.testsuite.util.TokenSignatureUtil;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
import org.keycloak.util.TokenUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URISyntaxException;
|
||||
|
@ -199,6 +204,10 @@ public class AuthorizationTokenEncryptionTest extends AbstractTestRealmKeycloakT
|
|||
byte[] decodedString = TokenUtil.jweKeyEncryptionVerifyAndDecode(decryptionKEK, jweStr, algorithmProvider, encryptionProvider);
|
||||
String authorizationTokenString = new String(decodedString, "UTF-8");
|
||||
|
||||
// a nested JWT (signed and encrypted JWT) needs to set "JWT" to its JOSE Header's "cty" field
|
||||
JWEHeader jweHeader = (JWEHeader) getHeader(parts[0]);
|
||||
Assert.assertEquals("JWT", jweHeader.getContentType());
|
||||
|
||||
// verify JWS
|
||||
AuthorizationResponseToken authorizationToken = oauth.verifyAuthorizationResponseToken(authorizationTokenString);
|
||||
Assert.assertEquals("test-app", authorizationToken.getAudience()[0]);
|
||||
|
@ -245,6 +254,15 @@ public class AuthorizationTokenEncryptionTest extends AbstractTestRealmKeycloakT
|
|||
return jweEncryptionProvider;
|
||||
}
|
||||
|
||||
private JOSEHeader getHeader(String base64Header) {
|
||||
try {
|
||||
byte[] decodedHeader = Base64Url.decode(base64Header);
|
||||
return JsonSerialization.readValue(decodedHeader, JWEHeader.class);
|
||||
} catch (IOException ioe) {
|
||||
throw new RuntimeException(ioe);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@UncaughtServerErrorExpected
|
||||
public void testAuthorizationEncryptionWithoutEncryptionKEK() throws MalformedURLException, URISyntaxException {
|
||||
|
|
|
@ -22,13 +22,16 @@ import org.junit.Rule;
|
|||
import org.junit.Test;
|
||||
import org.keycloak.OAuthErrorException;
|
||||
import org.keycloak.admin.client.resource.ClientResource;
|
||||
import org.keycloak.common.util.Base64Url;
|
||||
import org.keycloak.common.util.PemUtils;
|
||||
import org.keycloak.crypto.AesCbcHmacShaContentEncryptionProvider;
|
||||
import org.keycloak.crypto.AesGcmContentEncryptionProvider;
|
||||
import org.keycloak.crypto.Algorithm;
|
||||
import org.keycloak.crypto.RsaCekManagementProvider;
|
||||
import org.keycloak.jose.JOSEHeader;
|
||||
import org.keycloak.jose.jwe.JWEConstants;
|
||||
import org.keycloak.jose.jwe.JWEException;
|
||||
import org.keycloak.jose.jwe.JWEHeader;
|
||||
import org.keycloak.jose.jwe.alg.JWEAlgorithmProvider;
|
||||
import org.keycloak.jose.jwe.enc.JWEEncryptionProvider;
|
||||
import org.keycloak.protocol.oidc.OIDCAdvancedConfigWrapper;
|
||||
|
@ -52,8 +55,10 @@ import org.keycloak.testsuite.util.ClientManager;
|
|||
import org.keycloak.testsuite.util.OAuthClient;
|
||||
import org.keycloak.testsuite.util.OAuthClient.AccessTokenResponse;
|
||||
import org.keycloak.testsuite.util.TokenSignatureUtil;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
import org.keycloak.util.TokenUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.PrivateKey;
|
||||
import java.util.List;
|
||||
|
@ -220,6 +225,10 @@ public class IdTokenEncryptionTest extends AbstractTestRealmKeycloakTest {
|
|||
Map<String, String> keyPair = oidcClientEndpointsResource.getKeysAsPem();
|
||||
PrivateKey decryptionKEK = PemUtils.decodePrivateKey(keyPair.get("privateKey"));
|
||||
|
||||
// a nested JWT (signed and encrypted JWT) needs to set "JWT" to its JOSE Header's "cty" field
|
||||
JWEHeader jweHeader = (JWEHeader) getHeader(parts[0]);
|
||||
Assert.assertEquals("JWT", jweHeader.getContentType());
|
||||
|
||||
// verify and decrypt JWE
|
||||
JWEAlgorithmProvider algorithmProvider = getJweAlgorithmProvider(algAlgorithm);
|
||||
JWEEncryptionProvider encryptionProvider = getJweEncryptionProvider(encAlgorithm);
|
||||
|
@ -271,6 +280,15 @@ public class IdTokenEncryptionTest extends AbstractTestRealmKeycloakTest {
|
|||
return jweEncryptionProvider;
|
||||
}
|
||||
|
||||
private JOSEHeader getHeader(String base64Header) {
|
||||
try {
|
||||
byte[] decodedHeader = Base64Url.decode(base64Header);
|
||||
return JsonSerialization.readValue(decodedHeader, JWEHeader.class);
|
||||
} catch (IOException ioe) {
|
||||
throw new RuntimeException(ioe);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@UncaughtServerErrorExpected
|
||||
public void testIdTokenEncryptionWithoutEncryptionKEK() {
|
||||
|
|
Loading…
Reference in a new issue