diff --git a/http/oidc/src/main/java/org/wildfly/security/http/oidc/ElytronMessages.java b/http/oidc/src/main/java/org/wildfly/security/http/oidc/ElytronMessages.java
index 1cc55aafdc..376dbaea73 100644
--- a/http/oidc/src/main/java/org/wildfly/security/http/oidc/ElytronMessages.java
+++ b/http/oidc/src/main/java/org/wildfly/security/http/oidc/ElytronMessages.java
@@ -20,7 +20,6 @@
import static org.jboss.logging.Logger.Level.DEBUG;
import static org.jboss.logging.Logger.Level.ERROR;
-import static org.jboss.logging.Logger.Level.INFO;
import static org.jboss.logging.Logger.Level.WARN;
import static org.jboss.logging.annotations.Message.NONE;
@@ -238,17 +237,26 @@ interface ElytronMessages extends BasicLogger {
@Message(id = 23057, value = "Invalid keystore configuration for signing Request Objects.")
IOException invalidKeyStoreConfiguration();
- @Message(id = 23058, value = "The signature algorithm specified is not supported by the OpenID Provider.")
+ @Message(id = 23058, value = "The request object signature algorithm specified is not supported by the OpenID Provider.")
IOException invalidRequestObjectSignatureAlgorithm();
- @Message(id = 23059, value = "The encryption algorithm specified is not supported by the OpenID Provider.")
+ @Message(id = 23059, value = "The request object encryption algorithm specified is not supported by the OpenID Provider.")
IOException invalidRequestObjectEncryptionAlgorithm();
- @Message(id = 23060, value = "The content encryption algorithm specified is not supported by the OpenID Provider.")
+ @Message(id = 23060, value = "The request object content encryption algorithm specified is not supported by the OpenID Provider.")
IOException invalidRequestObjectContentEncryptionAlgorithm();
- @LogMessage(level = INFO)
+ @LogMessage(level = WARN)
@Message(id = 23061, value = "The OpenID provider does not support request parameters. Sending the request using OAuth2 format.")
void requestParameterNotSupported();
+
+ @Message(id = 23062, value = "Both request object encryption algorithm and request object content encryption algorithm must be configured to encrypt the request object.")
+ IllegalArgumentException invalidRequestEncryptionAlgorithmConfiguration();
+
+ @Message(id = 23063, value = "Failed to create the authentication request with request or request_uri parameter.")
+ RuntimeException unableToCreateRequestWithRequestParameter();
+
+ @Message (id = 23064, value = "Failed to connect with the OpenID provider.")
+ RuntimeException failedToConnectToOidcProvider(@Cause Exception cause);
}
diff --git a/http/oidc/src/main/java/org/wildfly/security/http/oidc/JWKPublicKeySetExtractor.java b/http/oidc/src/main/java/org/wildfly/security/http/oidc/JWKPublicKeySetExtractor.java
index 4069b73b7b..b2acd89da0 100644
--- a/http/oidc/src/main/java/org/wildfly/security/http/oidc/JWKPublicKeySetExtractor.java
+++ b/http/oidc/src/main/java/org/wildfly/security/http/oidc/JWKPublicKeySetExtractor.java
@@ -1,6 +1,6 @@
/*
* JBoss, Home of Professional Open Source.
- * Copyright 2020 Red Hat, Inc., and individual contributors
+ * Copyright 2024 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,26 +19,88 @@
package org.wildfly.security.http.oidc;
import static org.apache.http.HttpHeaders.ACCEPT;
+import static org.wildfly.security.http.oidc.ElytronMessages.log;
import static org.wildfly.security.http.oidc.Oidc.JSON_CONTENT_TYPE;
-import java.io.IOException;
+import java.security.PublicKey;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
import org.apache.http.client.methods.HttpGet;
-import org.jose4j.lang.JoseException;
+import org.wildfly.security.jose.jwk.JWK;
+import org.wildfly.security.jose.jwk.JWKParser;
import org.wildfly.security.jose.jwk.JsonWebKeySet;
+
/**
* A public key locator that dynamically obtains the public key from an OpenID
* provider by sending a request to the provider's {@code jwks_uri} when needed.
*
* @author Prarthona Paul
* */
-public class JWKPublicKeySetExtractor implements OidcPublicKeyExtractor {
+class JWKPublicKeySetExtractor implements PublicKeyLocator {
+ private Map currentKeys = new ConcurrentHashMap<>();
+
+ private volatile int lastRequestTime = 0;
public JWKPublicKeySetExtractor() {
}
+
@Override
- public JsonWebKeySet extractPublicKeySet(OidcClientConfiguration config) throws IOException, JoseException {
+ public PublicKey getPublicKey(String kid, OidcClientConfiguration config) {
+ int minTimeBetweenRequests = config.getMinTimeBetweenJwksRequests();
+ int publicKeyCacheTtl = config.getPublicKeyCacheTtl();
+ int currentTime = getCurrentTime();
+
+ PublicKey publicKey = lookupCachedKey(publicKeyCacheTtl, currentTime, kid);
+ if (publicKey != null) {
+ return publicKey;
+ }
+
+ synchronized (this) {
+ currentTime = getCurrentTime();
+ if (currentTime > lastRequestTime + minTimeBetweenRequests) {
+ sendRequest(kid, config);
+ lastRequestTime = currentTime;
+ } else {
+ log.debug("Won't send request to jwks url. Last request time was " + lastRequestTime);
+ }
+ return lookupCachedKey(publicKeyCacheTtl, currentTime, kid);
+ }
+
+ }
+
+ @Override
+ public void reset(OidcClientConfiguration config) {
+ synchronized (this) {
+ sendRequest("enc", config);
+ lastRequestTime = getCurrentTime();
+ }
+ }
+
+ private PublicKey lookupCachedKey(int publicKeyCacheTtl, int currentTime, String kid) {
+ if (lastRequestTime + publicKeyCacheTtl > currentTime && kid != null) {
+ return currentKeys.get(kid);
+ } else {
+ return null;
+ }
+ }
+
+ private static int getCurrentTime() {
+ return (int) (System.currentTimeMillis() / 1000);
+ }
+
+ private void sendRequest(String kid, OidcClientConfiguration config) {
HttpGet request = new HttpGet(config.getJwksUrl());
request.addHeader(ACCEPT, JSON_CONTENT_TYPE);
- return Oidc.sendJsonHttpRequest(config, request, JsonWebKeySet.class);
+ try {
+ JWK[] jwkList = Oidc.sendJsonHttpRequest(config, request, JsonWebKeySet.class).getKeys();
+ for (JWK jwk : jwkList) {
+ if (jwk.getPublicKeyUse().equals(kid)) { //JWTs are to be encrypted with public keys shared by the OpenID provider and decrypted by the private key they hold
+ currentKeys.clear();
+ currentKeys.put(kid, new JWKParser(jwk).toPublicKey());
+ }
+ }
+ } catch (OidcException e) {
+ log.error("Error when sending request to retrieve public keys", e);
+ }
}
-
}
diff --git a/http/oidc/src/main/java/org/wildfly/security/http/oidc/JWTClientCredentialsProvider.java b/http/oidc/src/main/java/org/wildfly/security/http/oidc/JWTClientCredentialsProvider.java
index 5ea6383e7a..13df213373 100644
--- a/http/oidc/src/main/java/org/wildfly/security/http/oidc/JWTClientCredentialsProvider.java
+++ b/http/oidc/src/main/java/org/wildfly/security/http/oidc/JWTClientCredentialsProvider.java
@@ -19,6 +19,7 @@
package org.wildfly.security.http.oidc;
import static org.wildfly.security.http.oidc.ElytronMessages.log;
+import static org.wildfly.security.http.oidc.JWTSigningUtils.loadKeyPairFromKeyStore;
import static org.wildfly.security.http.oidc.Oidc.CLIENT_ASSERTION;
import static org.wildfly.security.http.oidc.Oidc.CLIENT_ASSERTION_TYPE;
import static org.wildfly.security.http.oidc.Oidc.CLIENT_ASSERTION_TYPE_JWT;
@@ -109,7 +110,7 @@ public void init(OidcClientConfiguration oidcClientConfiguration, Object credent
clientKeyAlias = oidcClientConfiguration.getResourceName();
}
- KeyPair keyPair = new JWTSigningUtils().loadKeyPairFromKeyStore(clientKeyStoreFile, clientKeyStorePassword, clientKeyPassword, clientKeyAlias, clientKeyStoreType);
+ KeyPair keyPair = loadKeyPairFromKeyStore(clientKeyStoreFile, clientKeyStorePassword, clientKeyPassword, clientKeyAlias, clientKeyStoreType);
setupKeyPair(keyPair);
this.tokenTimeout = asInt(cfg, "token-timeout", 10);
}
diff --git a/http/oidc/src/main/java/org/wildfly/security/http/oidc/JWTSigning.java b/http/oidc/src/main/java/org/wildfly/security/http/oidc/JWTSigning.java
deleted file mode 100644
index 0b9207934c..0000000000
--- a/http/oidc/src/main/java/org/wildfly/security/http/oidc/JWTSigning.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2023 Red Hat, Inc., and individual contributors
- * as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.wildfly.security.http.oidc;
-
-import java.io.InputStream;
-import java.security.KeyPair;
-
-/**
- * An interface to obtain the KeyPair from a keystore file.
- *
- * @author Prarthona Paul
- */
-
-public interface JWTSigning {
- /**
- * @param keyStoreFile the path to the keystore file
- * @param storePassword the password for the keystore file
- * @param keyPassword the password for the key we would like ot extract from the keystore
- * @param keyAlias the alias for the key that uniquely identifies it
- * @param keyStoreType the type of keystore we are trying to access
- * @return the private-public keypair extracted from the keystore
- */
- KeyPair loadKeyPairFromKeyStore(String keyStoreFile, String storePassword, String keyPassword, String keyAlias, String keyStoreType);
-
- /**
- * @param keystoreFile the path the keystore file we are trying to access
- * @return the contents of the file as an inputStream
- */
- InputStream findFile(String keystoreFile);
-}
diff --git a/http/oidc/src/main/java/org/wildfly/security/http/oidc/JWTSigningUtils.java b/http/oidc/src/main/java/org/wildfly/security/http/oidc/JWTSigningUtils.java
index 4725e0d5e8..e9074aee13 100644
--- a/http/oidc/src/main/java/org/wildfly/security/http/oidc/JWTSigningUtils.java
+++ b/http/oidc/src/main/java/org/wildfly/security/http/oidc/JWTSigningUtils.java
@@ -25,6 +25,7 @@
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
+import java.security.cert.Certificate;
import static org.wildfly.security.http.oidc.ElytronMessages.log;
import static org.wildfly.security.http.oidc.Oidc.PROTOCOL_CLASSPATH;
@@ -35,18 +36,17 @@
* @author Prarthona Paul
*/
-public class JWTSigningUtils implements JWTSigning{
- public JWTSigningUtils() {}
+public class JWTSigningUtils {
+ private JWTSigningUtils() {}
- @Override
- public KeyPair loadKeyPairFromKeyStore(String keyStoreFile, String storePassword, String keyPassword, String keyAlias, String keyStoreType) {
+ public static KeyPair loadKeyPairFromKeyStore(String keyStoreFile, String storePassword, String keyPassword, String keyAlias, String keyStoreType) {
InputStream stream = findFile(keyStoreFile);
try {
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(stream, storePassword.toCharArray());
PrivateKey privateKey = (PrivateKey) keyStore.getKey(keyAlias, keyPassword.toCharArray());
if (privateKey == null) {
- log.unableToLoadKeyWithAlias(keyAlias);
+ throw log.unableToLoadKeyWithAlias(keyAlias);
}
PublicKey publicKey = keyStore.getCertificate(keyAlias).getPublicKey();
return new KeyPair(publicKey, privateKey);
@@ -55,8 +55,7 @@ public KeyPair loadKeyPairFromKeyStore(String keyStoreFile, String storePassword
}
}
- @Override
- public InputStream findFile(String keystoreFile) {
+ public static InputStream findFile(String keystoreFile) {
if (keystoreFile.startsWith(PROTOCOL_CLASSPATH)) {
String classPathLocation = keystoreFile.replace(PROTOCOL_CLASSPATH, "");
// try current class classloader first
diff --git a/http/oidc/src/main/java/org/wildfly/security/http/oidc/Oidc.java b/http/oidc/src/main/java/org/wildfly/security/http/oidc/Oidc.java
index 36c5a763c0..44bdb9d382 100644
--- a/http/oidc/src/main/java/org/wildfly/security/http/oidc/Oidc.java
+++ b/http/oidc/src/main/java/org/wildfly/security/http/oidc/Oidc.java
@@ -45,6 +45,7 @@
public class Oidc {
public static final String ACCEPT = "Accept";
+ public static final String AUTHENTICATION_REQUEST_FORMAT = "authentication-request-format";
public static final String OIDC_NAME = "OIDC";
public static final String JSON_CONTENT_TYPE = "application/json";
public static final String HTML_CONTENT_TYPE = "text/html";
@@ -74,6 +75,14 @@ public class Oidc {
public static final String PASSWORD = "password";
public static final String PROMPT = "prompt";
public static final String REQUEST = "request";
+ public static final String REQUEST_OBJECT_CONTENT_ENCRYPTION_ALGORITHM = "request-object-content-encryption-algorithm";
+ public static final String REQUEST_OBJECT_ENCRYPTION_ALGORITHM = "request-object-encryption-algorithm";
+ public static final String REQUEST_OBJECT_SIGNING_ALGORITHM = "request-object-signing-algorithm";
+ public static final String REQUEST_OBJECT_SIGNING_KEYSTORE_FILE = "request-object-signing-keystore-file";
+ public static final String REQUEST_OBJECT_SIGNING_KEYSTORE_PASSWORD = "request-object-signing-keystore-password";
+ public static final String REQUEST_OBJECT_SIGNING_KEY_PASSWORD = "request-object-signing-key-password";
+ public static final String REQUEST_OBJECT_SIGNING_KEY_ALIAS = "request-object-signing-key-alias";
+ public static final String REQUEST_OBJECT_SIGNING_KEYSTORE_TYPE = "request-object-signing-keystore-type";
public static final String REQUEST_URI = "request_uri";
public static final String SCOPE = "scope";
public static final String UI_LOCALES = "ui_locales";
@@ -213,9 +222,9 @@ public enum AuthenticationFormat {
}
/**
- * Get the string value for this referral mode.
+ * Get the string value for this authentication format.
*
- * @return the string value for this referral mode
+ * @return the string value for this authentication format
*/
public String getValue() {
return value;
diff --git a/http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcClientConfiguration.java b/http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcClientConfiguration.java
index 5a1324137b..ec1c85090e 100644
--- a/http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcClientConfiguration.java
+++ b/http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcClientConfiguration.java
@@ -133,15 +133,16 @@ public enum RelativeUrlsUsed {
protected String tokenSignatureAlgorithm = DEFAULT_TOKEN_SIGNATURE_ALGORITHM;
protected String authenticationRequestFormat;
- protected String requestSignatureAlgorithm;
- protected String requestEncryptAlgorithm;
- protected String requestContentEncryptionMethod;
+ protected String requestObjectSignatureAlgorithm;
+ protected String requestObjectEncryptAlgorithm;
+ protected String requestObjectContentEncryptionMethod;
protected String pushedAuthorizationRequestEndpoint;
- protected String requestObjectSigningKeystoreFile;
+ protected String requestObjectSigningKeyStoreFile;
protected String requestObjectSigningKeyStorePass;
protected String requestObjectSigningKeyPass;
protected String requestObjectSigningKeyAlias;
- protected String requestObjectSigningKeystoreType;
+ protected String requestObjectSigningKeyStoreType;
+ protected JWKPublicKeySetExtractor encryptionPublicKeyLocator;
public OidcClientConfiguration() {
}
@@ -699,36 +700,36 @@ public void setAuthenticationRequestFormat(String authenticationRequestFormat )
this.authenticationRequestFormat = authenticationRequestFormat;
}
- public String getRequestSignatureAlgorithm() {
- return requestSignatureAlgorithm;
+ public String getRequestObjectSignatureAlgorithm() {
+ return requestObjectSignatureAlgorithm;
}
- public void setRequestSignatureAlgorithm(String requestSignatureAlgorithm) {
- this.requestSignatureAlgorithm = requestSignatureAlgorithm;
+ public void setRequestObjectSignatureAlgorithm(String requestObjectSignatureAlgorithm) {
+ this.requestObjectSignatureAlgorithm = requestObjectSignatureAlgorithm;
}
- public String getRequestEncryptAlgorithm() {
- return requestEncryptAlgorithm;
+ public String getRequestObjectEncryptAlgorithm() {
+ return requestObjectEncryptAlgorithm;
}
- public void setRequestEncryptAlgorithm(String requestEncryptAlgorithm) {
- this.requestEncryptAlgorithm = requestEncryptAlgorithm;
+ public void setRequestObjectEncryptAlgorithm(String requestObjectEncryptAlgorithm) {
+ this.requestObjectEncryptAlgorithm = requestObjectEncryptAlgorithm;
}
- public String getRequestContentEncryptionMethod() {
- return requestContentEncryptionMethod;
+ public String getRequestObjectContentEncryptionMethod() {
+ return requestObjectContentEncryptionMethod;
}
- public void setRequestContentEncryptionMethod(String requestContentEncryptionMethod) {
- this.requestContentEncryptionMethod = requestContentEncryptionMethod;
+ public void setRequestObjectContentEncryptionMethod(String requestObjectContentEncryptionMethod) {
+ this.requestObjectContentEncryptionMethod = requestObjectContentEncryptionMethod;
}
- public String getRequestObjectSigningKeystoreFile() {
- return requestObjectSigningKeystoreFile;
+ public String getRequestObjectSigningKeyStoreFile() {
+ return requestObjectSigningKeyStoreFile;
}
- public void setRequestObjectSigningKeystoreFile(String keyStoreFile) {
- this.requestObjectSigningKeystoreFile = keyStoreFile;
+ public void setRequestObjectSigningKeyStoreFile(String keyStoreFile) {
+ this.requestObjectSigningKeyStoreFile = keyStoreFile;
}
public String getRequestObjectSigningKeyStorePassword() {
@@ -747,12 +748,12 @@ public void setRequestObjectSigningKeyPassword(String pass) {
this.requestObjectSigningKeyPass = pass;
}
- public String getRequestObjectSigningKeystoreType() {
- return requestObjectSigningKeystoreType;
+ public String getRequestObjectSigningKeyStoreType() {
+ return requestObjectSigningKeyStoreType;
}
- public void setRequestObjectSigningKeystoreType(String type) {
- this.requestObjectSigningKeystoreType = type;
+ public void setRequestObjectSigningKeyStoreType(String type) {
+ this.requestObjectSigningKeyStoreType = type;
}
public String getRequestObjectSigningKeyAlias() {
@@ -770,4 +771,12 @@ public String getPushedAuthorizationRequestEndpoint() {
public void setPushedAuthorizationRequestEndpoint(String url) {
this.pushedAuthorizationRequestEndpoint = url;
}
+
+ public void setEncryptionPublicKeyLocator(JWKPublicKeySetExtractor publicKeySetExtractor) {
+ this.encryptionPublicKeyLocator = publicKeySetExtractor;
+ }
+
+ public JWKPublicKeySetExtractor getEncryptionPublicKeyLocator() {
+ return this.encryptionPublicKeyLocator;
+ }
}
diff --git a/http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcClientConfigurationBuilder.java b/http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcClientConfigurationBuilder.java
index 6b95391e59..8a0703f5d5 100644
--- a/http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcClientConfigurationBuilder.java
+++ b/http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcClientConfigurationBuilder.java
@@ -110,25 +110,29 @@ protected OidcClientConfiguration internalBuild(final OidcJsonConfiguration oidc
} else {
oidcClientConfiguration.setAuthenticationRequestFormat(REQUEST_TYPE_OAUTH2.getValue());
}
- if (oidcJsonConfiguration.getRequestSignatureAlgorithm() != null) {
- oidcClientConfiguration.setRequestSignatureAlgorithm(oidcJsonConfiguration.getRequestSignatureAlgorithm());
+ if (oidcJsonConfiguration.getRequestObjectSignatureAlgorithm() != null) {
+ oidcClientConfiguration.setRequestObjectSignatureAlgorithm(oidcJsonConfiguration.getRequestObjectSignatureAlgorithm());
} else {
- oidcClientConfiguration.setRequestSignatureAlgorithm(NONE);
+ oidcClientConfiguration.setRequestObjectSignatureAlgorithm(NONE);
}
- if (oidcJsonConfiguration.getRequestEncryptAlgorithm() != null && oidcJsonConfiguration.getRequestContentEncryptionMethod() != null) { //both are required to encrypt the request object
- oidcClientConfiguration.setRequestEncryptAlgorithm(oidcJsonConfiguration.getRequestEncryptAlgorithm());
- oidcClientConfiguration.setRequestContentEncryptionMethod(oidcJsonConfiguration.getRequestContentEncryptionMethod());
+ if (oidcJsonConfiguration.getRequestEncryptAlgorithm() != null && oidcJsonConfiguration.getRequestObjectContentEncryptionMethod() != null) { //both are required to encrypt the request object
+ oidcClientConfiguration.setRequestObjectEncryptAlgorithm(oidcJsonConfiguration.getRequestEncryptAlgorithm());
+ oidcClientConfiguration.setRequestObjectContentEncryptionMethod(oidcJsonConfiguration.getRequestObjectContentEncryptionMethod());
+ JWKPublicKeySetExtractor encryptionPublicKeyLocator = new JWKPublicKeySetExtractor();
+ oidcClientConfiguration.setEncryptionPublicKeyLocator(encryptionPublicKeyLocator);
+ } else if (oidcClientConfiguration.getRequestObjectEncryptAlgorithm() != null || oidcClientConfiguration.getRequestObjectContentEncryptionMethod() != null) { //if only one is specified, that is not correct
+ throw log.invalidRequestEncryptionAlgorithmConfiguration();
}
if (oidcJsonConfiguration.getRequestObjectSigningKeyStoreFile() != null
- && oidcJsonConfiguration.getRequestObjectSigningKeystorePassword() != null
+ && oidcJsonConfiguration.getRequestObjectSigningKeyStorePassword() != null
&& oidcJsonConfiguration.getRequestObjectSigningKeyPassword() != null
&& oidcJsonConfiguration.getRequestObjectSigningKeyAlias() != null) {
- oidcClientConfiguration.setRequestObjectSigningKeystoreFile(oidcJsonConfiguration.getRequestObjectSigningKeyStoreFile());
- oidcClientConfiguration.setRequestObjectSigningKeyStorePassword(oidcJsonConfiguration.getRequestObjectSigningKeystorePassword());
+ oidcClientConfiguration.setRequestObjectSigningKeyStoreFile(oidcJsonConfiguration.getRequestObjectSigningKeyStoreFile());
+ oidcClientConfiguration.setRequestObjectSigningKeyStorePassword(oidcJsonConfiguration.getRequestObjectSigningKeyStorePassword());
oidcClientConfiguration.setRequestObjectSigningKeyPassword(oidcJsonConfiguration.getRequestObjectSigningKeyPassword());
oidcClientConfiguration.setRequestObjectSigningKeyAlias(oidcJsonConfiguration.getRequestObjectSigningKeyAlias());
- if (oidcJsonConfiguration.getRequestObjectSigningKeystoreType() != null) {
- oidcClientConfiguration.setRequestObjectSigningKeystoreType(oidcJsonConfiguration.getRequestObjectSigningKeystoreType());
+ if (oidcJsonConfiguration.getRequestObjectSigningKeyStoreType() != null) {
+ oidcClientConfiguration.setRequestObjectSigningKeyStoreType(oidcJsonConfiguration.getRequestObjectSigningKeyStoreType());
}
}
if (oidcJsonConfiguration.getPrincipalAttribute() != null) oidcClientConfiguration.setPrincipalAttribute(oidcJsonConfiguration.getPrincipalAttribute());
@@ -224,4 +228,5 @@ public static OidcJsonConfiguration loadOidcJsonConfiguration(InputStream is) {
public static OidcClientConfiguration build(OidcJsonConfiguration oidcJsonConfiguration) {
return new OidcClientConfigurationBuilder().internalBuild(oidcJsonConfiguration);
}
+
}
diff --git a/http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcClientContext.java b/http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcClientContext.java
index 62424e7b5c..409f817ea4 100644
--- a/http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcClientContext.java
+++ b/http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcClientContext.java
@@ -537,43 +537,43 @@ public void setAuthenticationRequestFormat(String authFormat) {
}
@Override
- public String getRequestSignatureAlgorithm() {
- return delegate.getRequestSignatureAlgorithm();
+ public String getRequestObjectSignatureAlgorithm() {
+ return delegate.getRequestObjectSignatureAlgorithm();
}
@Override
- public void setRequestSignatureAlgorithm(String requestSignature) {
- delegate.setRequestSignatureAlgorithm(requestSignature);
+ public void setRequestObjectSignatureAlgorithm(String requestSignature) {
+ delegate.setRequestObjectSignatureAlgorithm(requestSignature);
}
@Override
- public String getRequestEncryptAlgorithm() {
- return delegate.getRequestEncryptAlgorithm();
+ public String getRequestObjectEncryptAlgorithm() {
+ return delegate.getRequestObjectEncryptAlgorithm();
}
@Override
- public void setRequestEncryptAlgorithm(String algorithm) {
- delegate.setRequestEncryptAlgorithm(algorithm);
+ public void setRequestObjectEncryptAlgorithm(String algorithm) {
+ delegate.setRequestObjectEncryptAlgorithm(algorithm);
}
@Override
- public String getRequestContentEncryptionMethod() {
- return delegate.requestContentEncryptionMethod;
+ public String getRequestObjectContentEncryptionMethod() {
+ return delegate.requestObjectContentEncryptionMethod;
}
@Override
- public void setRequestContentEncryptionMethod (String enc) {
- delegate.requestContentEncryptionMethod = enc;
+ public void setRequestObjectContentEncryptionMethod (String enc) {
+ delegate.requestObjectContentEncryptionMethod = enc;
}
@Override
- public String getRequestObjectSigningKeystoreFile() {
- return delegate.requestObjectSigningKeystoreFile;
+ public String getRequestObjectSigningKeyStoreFile() {
+ return delegate.requestObjectSigningKeyStoreFile;
}
@Override
- public void setRequestObjectSigningKeystoreFile(String keyStoreFile) {
- delegate.requestObjectSigningKeystoreFile = keyStoreFile;
+ public void setRequestObjectSigningKeyStoreFile(String keyStoreFile) {
+ delegate.requestObjectSigningKeyStoreFile = keyStoreFile;
}
@Override
@@ -597,13 +597,13 @@ public void setRequestObjectSigningKeyPassword(String pass) {
}
@Override
- public String getRequestObjectSigningKeystoreType() {
- return delegate.requestObjectSigningKeystoreType;
+ public String getRequestObjectSigningKeyStoreType() {
+ return delegate.requestObjectSigningKeyStoreType;
}
@Override
- public void setRequestObjectSigningKeystoreType(String type) {
- delegate.requestObjectSigningKeystoreType = type;
+ public void setRequestObjectSigningKeyStoreType(String type) {
+ delegate.requestObjectSigningKeyStoreType = type;
}
@Override
diff --git a/http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcJsonConfiguration.java b/http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcJsonConfiguration.java
index 8871e30ce0..1bfdb9daff 100644
--- a/http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcJsonConfiguration.java
+++ b/http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcJsonConfiguration.java
@@ -45,9 +45,11 @@
"register-node-at-startup", "register-node-period", "token-store", "adapter-state-cookie-path", "principal-attribute",
"proxy-url", "turn-off-change-session-id-on-login", "token-minimum-time-to-live",
"min-time-between-jwks-requests", "public-key-cache-ttl",
- "ignore-oauth-query-parameter", "verify-token-audience", "token-signature-algorithm", "scope"
+ "ignore-oauth-query-parameter", "verify-token-audience", "token-signature-algorithm", "scope",
"authentication-request-format", "request-object-signing-algorithm", "request-object-encryption-algorithm",
- "request-object-content-encryption-algorithm"
+ "request-object-content-encryption-algorithm", "request-object-signing-keystore-file",
+ "request-object-signing-keystore-password","request-object-signing-key-password", "request-object-signing-key-alias",
+ "request-object-signing-keystore-type"
})
public class OidcJsonConfiguration {
@@ -63,16 +65,18 @@ public class OidcJsonConfiguration {
protected String clientKeystore;
@JsonProperty("client-keystore-password")
protected String clientKeystorePassword;
+ @JsonProperty("client-key-password")
+ protected String clientKeyPassword;
@JsonProperty("request-object-signing-keystore-file")
protected String requestObjectSigningKeyStoreFile;
@JsonProperty("request-object-signing-keystore-password")
- protected String requestObjectSigningKeystorePassword;
+ protected String requestObjectSigningKeyStorePassword;
@JsonProperty("request-object-signing-key-password")
protected String requestObjectSigningKeyPassword;
@JsonProperty("request-object-signing-key-alias")
protected String requestObjectSigningKeyAlias;
@JsonProperty("request-object-signing-keystore-type")
- protected String requestObjectSigningKeystoreType;
+ protected String requestObjectSigningKeyStoreType;
@JsonProperty("connection-pool-size")
protected int connectionPoolSize = 20;
@JsonProperty("always-refresh-token")
@@ -155,13 +159,13 @@ public class OidcJsonConfiguration {
protected String authenticationRequestFormat;
@JsonProperty("request-object-signing-algorithm")
- protected String requestSignatureAlgorithm;
+ protected String requestObjectSignatureAlgorithm;
@JsonProperty("request-object-encryption-algorithm")
- protected String requestEncryptAlgorithm;
+ protected String requestObjectEncryptAlgorithm;
@JsonProperty("request-object-content-encryption-algorithm")
- protected String requestContentEncryptionMethod;
+ protected String requestObjectContentEncryptionMethod;
/**
* The Proxy url to use for requests to the auth-server, configurable via the adapter config property {@code proxy-url}.
@@ -216,12 +220,12 @@ public void setClientKeystore(String clientKeystore) {
this.clientKeystore = clientKeystore;
}
- public String getRequestObjectSigningKeystoreType() {
- return requestObjectSigningKeystoreType;
+ public String getRequestObjectSigningKeyStoreType() {
+ return requestObjectSigningKeyStoreType;
}
- public void setRequestObjectSigningKeystoreType(String type) {
- this.requestObjectSigningKeystoreType = type;
+ public void setRequestObjectSigningKeyStoreType(String type) {
+ this.requestObjectSigningKeyStoreType = type;
}
public String getRequestObjectSigningKeyAlias() {
@@ -240,16 +244,24 @@ public void setClientKeystorePassword(String clientKeystorePassword) {
this.clientKeystorePassword = clientKeystorePassword;
}
+ public String getClientKeyPassword() {
+ return clientKeyPassword;
+ }
+
public String getRequestObjectSigningKeyPassword() {
return requestObjectSigningKeyPassword;
}
- public String getRequestObjectSigningKeystorePassword() {
- return requestObjectSigningKeystorePassword;
+ public String getRequestObjectSigningKeyStorePassword() {
+ return requestObjectSigningKeyStorePassword;
+ }
+
+ public void setClientKeyPassword(String clientKeyPassword) {
+ this.clientKeyPassword = clientKeyPassword;
}
- public void setRequestObjectSigningKeystorePassword(String requestObjectSigningKeystorePassword) {
- this.requestObjectSigningKeystorePassword = requestObjectSigningKeystorePassword;
+ public void setRequestObjectSigningKeyStorePassword(String requestObjectSigningKeyStorePassword) {
+ this.requestObjectSigningKeyStorePassword = requestObjectSigningKeyStorePassword;
}
public void setRequestObjectSigningKeyPassword(String requestObjectSigningKeyPassword) {
@@ -580,28 +592,28 @@ public void setAuthenticationRequestFormat(String authenticationRequestFormat) {
this.authenticationRequestFormat = authenticationRequestFormat;
}
- public String getRequestSignatureAlgorithm() {
- return requestSignatureAlgorithm;
+ public String getRequestObjectSignatureAlgorithm() {
+ return requestObjectSignatureAlgorithm;
}
- public void setRequestSignatureAlgorithm(String requestSignatureAlgorithm) {
- this.requestSignatureAlgorithm = requestSignatureAlgorithm;
+ public void setRequestSignatureAlgorithm(String requestObjectSignatureAlgorithm) {
+ this.requestObjectSignatureAlgorithm = requestObjectSignatureAlgorithm;
}
public String getRequestEncryptAlgorithm() {
- return requestEncryptAlgorithm;
+ return requestObjectEncryptAlgorithm;
}
- public void setRequestEncryptAlgorithm(String requestSignatureAlgorithm) {
- this.requestEncryptAlgorithm = requestSignatureAlgorithm;
+ public void setRequestObjectEncryptAlgorithm(String requestObjectSignatureAlgorithm) {
+ this.requestObjectEncryptAlgorithm = requestObjectSignatureAlgorithm;
}
- public String getRequestContentEncryptionMethod() {
- return requestContentEncryptionMethod;
+ public String getRequestObjectContentEncryptionMethod() {
+ return requestObjectContentEncryptionMethod;
}
- public void setRequestContentEncryptionMethod (String requestContentEncryptionMethod) {
- this.requestContentEncryptionMethod = requestContentEncryptionMethod;
+ public void setRequestObjectContentEncryptionMethod (String requestObjectContentEncryptionMethod) {
+ this.requestObjectContentEncryptionMethod = requestObjectContentEncryptionMethod;
}
}
diff --git a/http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcProviderMetadata.java b/http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcProviderMetadata.java
index 6da737f5b1..af005e0031 100644
--- a/http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcProviderMetadata.java
+++ b/http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcProviderMetadata.java
@@ -440,7 +440,7 @@ public String getPushedAuthorizationRequestEndpoint() {
return pushedAuthorizationRequestEndpoint;
}
- public void setPushedAuthorizationRequestEndpoint (String url) {
+ public void setPushedAuthorizationRequestEndpoint(String url) {
this.pushedAuthorizationRequestEndpoint = url;
}
diff --git a/http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcPublicKeyExtractor.java b/http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcPublicKeyExtractor.java
deleted file mode 100644
index 75b5294341..0000000000
--- a/http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcPublicKeyExtractor.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2023 Red Hat, Inc., and individual contributors
- * as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.wildfly.security.http.oidc;
-
-import org.wildfly.security.jose.jwk.JsonWebKeySet;
-
-/**
- * An interface to send a GET request to the JWKSUrl of the OpenID
- * provider and obtain the public key.
- *
- * @author Prarthona Paul
- */
-public interface OidcPublicKeyExtractor {
- /**
- * @param config the OpenID Connect client configuration
- * @return a Json Web Key Set with the public keys for the OpenID provider
- */
- JsonWebKeySet extractPublicKeySet(OidcClientConfiguration config) throws Exception;
-
-}
diff --git a/http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcRequestAuthenticator.java b/http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcRequestAuthenticator.java
index 1d3087cbfd..c18453f704 100644
--- a/http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcRequestAuthenticator.java
+++ b/http/oidc/src/main/java/org/wildfly/security/http/oidc/OidcRequestAuthenticator.java
@@ -58,6 +58,7 @@
import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.security.KeyPair;
+import java.security.PublicKey;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
@@ -82,8 +83,6 @@
import org.jose4j.keys.HmacKey;
import org.jose4j.lang.JoseException;
import org.wildfly.security.http.HttpConstants;
-import org.wildfly.security.jose.jwk.JWK;
-import org.wildfly.security.jose.jwk.JWKParser;
/**
@@ -225,7 +224,11 @@ protected String getRedirectUri(String state) {
case REQUEST:
if (deployment.getRequestParameterSupported()) {
// add request objects into request parameter
- createRequestWithRequestParameter(REQUEST, redirectUriBuilder, redirectUri, state, forwardedQueryParams);
+ try {
+ createRequestWithRequestParameter(REQUEST, redirectUriBuilder, redirectUri, state, forwardedQueryParams);
+ } catch (IOException | JoseException e) {
+ throw log.unableToCreateRequestWithRequestParameter();
+ }
} else {
// send request as usual
createOAuthRequest(redirectUriBuilder, redirectUri, state, forwardedQueryParams);
@@ -234,7 +237,11 @@ protected String getRedirectUri(String state) {
break;
case REQUEST_URI:
if (deployment.getRequestUriParameterSupported()) {
- createRequestWithRequestParameter(REQUEST_URI, redirectUriBuilder, redirectUri, state, forwardedQueryParams);
+ try {
+ createRequestWithRequestParameter(REQUEST_URI, redirectUriBuilder, redirectUri, state, forwardedQueryParams);
+ } catch (IOException | JoseException e) {
+ throw log.unableToCreateRequestWithRequestParameter();
+ }
} else {
// send request as usual
createOAuthRequest(redirectUriBuilder, redirectUri, state, forwardedQueryParams);
@@ -248,8 +255,6 @@ protected String getRedirectUri(String state) {
return redirectUriBuilder.build().toString();
} catch (URISyntaxException e) {
throw log.unableToCreateRedirectResponse(e);
- } catch (IOException | JoseException | InvalidJwtException e) {
- throw new RuntimeException(e);
}
}
@@ -260,7 +265,7 @@ protected URIBuilder createOAuthRequest(URIBuilder redirectUriBuilder, String re
return redirectUriBuilder;
}
- protected URIBuilder createRequestWithRequestParameter(String requestFormat, URIBuilder redirectUriBuilder, String redirectUri, String state, List forwardedQueryParams) throws JoseException, IOException, InvalidJwtException {
+ protected URIBuilder createRequestWithRequestParameter(String requestFormat, URIBuilder redirectUriBuilder, String redirectUri, String state, List forwardedQueryParams) throws JoseException, IOException {
String request = convertToRequestParameter(redirectUriBuilder, redirectUri, state, forwardedQueryParams);
switch (requestFormat) {
@@ -522,7 +527,7 @@ private void addScopes(String scopes, Set allScopes) {
}
}
- private String convertToRequestParameter(URIBuilder redirectUriBuilder, String redirectUri, String state, List forwardedQueryParams) throws IOException, JoseException {
+ private String convertToRequestParameter(URIBuilder redirectUriBuilder, String redirectUri, String state, List forwardedQueryParams) throws JoseException, IOException {
redirectUriBuilder.addParameter(SCOPE, OIDC_SCOPE);
JwtClaims jwtClaims = new JwtClaims();
@@ -541,24 +546,24 @@ private String convertToRequestParameter(URIBuilder redirectUriBuilder, String r
JsonWebSignature signedRequest = signRequest(jwtClaims);
// Encrypting optional
- if (deployment.getRequestEncryptAlgorithm() != null && !deployment.getRequestEncryptAlgorithm().isEmpty() &&
- deployment.getRequestContentEncryptionMethod() != null && !deployment.getRequestContentEncryptionMethod().isEmpty()) {
+ if (deployment.getRequestObjectEncryptAlgorithm() != null && !deployment.getRequestObjectEncryptAlgorithm().isEmpty() &&
+ deployment.getRequestObjectContentEncryptionMethod() != null && !deployment.getRequestObjectContentEncryptionMethod().isEmpty()) {
return encryptRequest(signedRequest).getCompactSerialization();
} else {
return signedRequest.getCompactSerialization();
}
}
- public KeyPair getkeyPair() throws IOException {
- if (deployment.getRequestObjectSigningKeystoreFile().contains(PROTOCOL_CLASSPATH)) {
- deployment.setRequestObjectSigningKeystoreFile(deployment.getRequestObjectSigningKeystoreFile().replace(PROTOCOL_CLASSPATH, Objects.requireNonNull(Thread.currentThread().getContextClassLoader().getResource("")).getPath()));
+ private static KeyPair getkeyPair(OidcClientConfiguration deployment) throws IOException {
+ if (deployment.getRequestObjectSigningKeyStoreFile().contains(PROTOCOL_CLASSPATH)) {
+ deployment.setRequestObjectSigningKeyStoreFile(deployment.getRequestObjectSigningKeyStoreFile().replace(PROTOCOL_CLASSPATH, Objects.requireNonNull(Thread.currentThread().getContextClassLoader().getResource("")).getPath()));
}
- if (!deployment.getRequestSignatureAlgorithm().equals(NONE) && deployment.getRequestObjectSigningKeystoreFile() == null){
+ if (!deployment.getRequestObjectSignatureAlgorithm().equals(NONE) && deployment.getRequestObjectSigningKeyStoreFile() == null){
throw log.invalidKeyStoreConfiguration();
} else {
- return new JWTSigningUtils().loadKeyPairFromKeyStore(deployment.getRequestObjectSigningKeystoreFile(),
+ return JWTSigningUtils.loadKeyPairFromKeyStore(deployment.getRequestObjectSigningKeyStoreFile(),
deployment.getRequestObjectSigningKeyStorePassword(), deployment.getRequestObjectSigningKeyPassword(),
- deployment.getRequestObjectSigningKeyAlias(), deployment.getRequestObjectSigningKeystoreType());
+ deployment.getRequestObjectSigningKeyAlias(), deployment.getRequestObjectSigningKeyStoreType());
}
}
@@ -566,52 +571,47 @@ public JsonWebSignature signRequest(JwtClaims jwtClaims) throws IOException, Jos
JsonWebSignature jsonWebSignature = new JsonWebSignature();
jsonWebSignature.setPayload(jwtClaims.toJson());
- if (!deployment.getRequestObjectSigningAlgValuesSupported().contains(deployment.getRequestSignatureAlgorithm())) {
+ if (!deployment.getRequestObjectSigningAlgValuesSupported().contains(deployment.getRequestObjectSignatureAlgorithm())) {
throw log.invalidRequestObjectSignatureAlgorithm();
} else {
- if (deployment.getRequestSignatureAlgorithm().contains(NONE)) { //unsigned
+ if (deployment.getRequestObjectSignatureAlgorithm().contains(NONE)) { //unsigned
jsonWebSignature.setAlgorithmConstraints(AlgorithmConstraints.NO_CONSTRAINTS);
jsonWebSignature.setAlgorithmHeaderValue(NONE);
- } else if (deployment.getRequestSignatureAlgorithm().contains(HMAC_SHA256)
- || deployment.getRequestSignatureAlgorithm().contains(HMAC_SHA384)
- || deployment.getRequestSignatureAlgorithm().contains(HMAC_SHA512)) { //signed with symmetric key
- jsonWebSignature.setAlgorithmHeaderValue(deployment.getRequestSignatureAlgorithm());
+ } else if (deployment.getRequestObjectSignatureAlgorithm().contains(HMAC_SHA256)
+ || deployment.getRequestObjectSignatureAlgorithm().contains(HMAC_SHA384)
+ || deployment.getRequestObjectSignatureAlgorithm().contains(HMAC_SHA512)) { //signed with symmetric key
+ jsonWebSignature.setAlgorithmHeaderValue(deployment.getRequestObjectSignatureAlgorithm());
Key key = new HmacKey(deployment.getResourceCredentials().get("secret").toString().getBytes(StandardCharsets.UTF_8)); //the client secret is a shared secret between the server and the client
jsonWebSignature.setDoKeyValidation(false); //skips validation so that size of the secret does not matter
jsonWebSignature.setKey(key);
} else { //signed with asymmetric key
- KeyPair keyPair = getkeyPair();
+ KeyPair keyPair = getkeyPair(deployment);
jsonWebSignature.setKey(keyPair.getPrivate());
- jsonWebSignature.setAlgorithmHeaderValue(deployment.getRequestSignatureAlgorithm());
+ jsonWebSignature.setAlgorithmHeaderValue(deployment.getRequestObjectSignatureAlgorithm());
}
jsonWebSignature.sign();
return jsonWebSignature;
}
}
- private JsonWebEncryption encryptRequest(JsonWebSignature signedRequest) throws IOException, JoseException {
- if (!deployment.getRequestObjectEncryptionAlgValuesSupported().contains(deployment.getRequestEncryptAlgorithm())) {
+ private JsonWebEncryption encryptRequest(JsonWebSignature signedRequest) throws JoseException, IOException {
+ if (!deployment.getRequestObjectEncryptionAlgValuesSupported().contains(deployment.getRequestObjectEncryptAlgorithm())) {
throw log.invalidRequestObjectEncryptionAlgorithm();
- } else if (!deployment.getRequestObjectContentEncryptionMethodsSupported().contains(deployment.getRequestContentEncryptionMethod())) {
+ } else if (!deployment.getRequestObjectContentEncryptionMethodsSupported().contains(deployment.getRequestObjectContentEncryptionMethod())) {
throw log.invalidRequestObjectContentEncryptionAlgorithm();
} else {
JsonWebEncryption jsonEncryption = new JsonWebEncryption();
jsonEncryption.setPayload(signedRequest.getCompactSerialization());
- jsonEncryption.setAlgorithmConstraints(new AlgorithmConstraints(AlgorithmConstraints.ConstraintType.PERMIT, deployment.getRequestEncryptAlgorithm(), deployment.getRequestContentEncryptionMethod()));
- jsonEncryption.setAlgorithmHeaderValue(deployment.getRequestEncryptAlgorithm());
- jsonEncryption.setEncryptionMethodHeaderParameter(deployment.getRequestContentEncryptionMethod());
- JWK[] jwkList = new JWKPublicKeySetExtractor().extractPublicKeySet(deployment).getKeys();
- for (JWK jwk : jwkList) {
- if (jwk.getPublicKeyUse().equals("enc")) { //JWTs are to be encrypted with public keys shared by the OpenID provider and decrypted by the private key they hold
- jsonEncryption.setKey(new JWKParser(jwk).toPublicKey());
- break;
- }
- }
+ jsonEncryption.setAlgorithmConstraints(new AlgorithmConstraints(AlgorithmConstraints.ConstraintType.PERMIT, deployment.getRequestObjectEncryptAlgorithm(), deployment.getRequestObjectContentEncryptionMethod()));
+ jsonEncryption.setAlgorithmHeaderValue(deployment.getRequestObjectEncryptAlgorithm());
+ jsonEncryption.setEncryptionMethodHeaderParameter(deployment.getRequestObjectContentEncryptionMethod());
+ PublicKey encPublicKey = deployment.getEncryptionPublicKeyLocator().getPublicKey("enc", deployment);
+ jsonEncryption.setKey(encPublicKey);
return jsonEncryption;
}
}
- private String getRequestUri(String request) throws IOException, InvalidJwtException {
+ private String getRequestUri(String request) throws OidcException {
HttpPost parRequest = new HttpPost(deployment.getPushedAuthorizationRequestEndpoint());
List formParams = new ArrayList();
formParams.add(new BasicNameValuePair(REQUEST, request));
@@ -620,21 +620,30 @@ private String getRequestUri(String request) throws IOException, InvalidJwtExcep
UrlEncodedFormEntity form = new UrlEncodedFormEntity(formParams, StandardCharsets.UTF_8);
parRequest.setEntity(form);
- HttpResponse response = deployment.getClient().execute(parRequest);
+
+ HttpResponse response;
+ try {
+ response = deployment.getClient().execute(parRequest);
+ } catch (Exception e) {
+ throw log.failedToConnectToOidcProvider(e);
+ }
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_CREATED) {
EntityUtils.consumeQuietly(response.getEntity());
throw log.unexpectedResponseCodeFromOidcProvider(response.getStatusLine().getStatusCode());
}
- InputStream inputStream = response.getEntity().getContent();
- StringBuilder textBuilder = new StringBuilder();
- try (Reader reader = new BufferedReader(new InputStreamReader
- (inputStream, StandardCharsets.UTF_8))) {
+ try {
+ InputStream inputStream = response.getEntity().getContent();
+ StringBuilder textBuilder = new StringBuilder();
+ Reader reader = new BufferedReader(new InputStreamReader
+ (inputStream, StandardCharsets.UTF_8));
int c = 0;
while ((c = reader.read()) != -1) {
textBuilder.append((char) c);
}
+ JwtClaims jwt = JwtClaims.parse(textBuilder.toString());
+ return jwt.getClaimValueAsString(REQUEST_URI);
+ } catch (IOException | InvalidJwtException e) {
+ throw log.failedToDecodeRequestUri(e);
}
- JwtClaims jwt = JwtClaims.parse(textBuilder.toString());
- return jwt.getClaimValueAsString(REQUEST_URI);
}
}
diff --git a/http/oidc/src/test/java/org/wildfly/security/http/oidc/KeycloakConfiguration.java b/http/oidc/src/test/java/org/wildfly/security/http/oidc/KeycloakConfiguration.java
index 831a921635..6aa511cce8 100644
--- a/http/oidc/src/test/java/org/wildfly/security/http/oidc/KeycloakConfiguration.java
+++ b/http/oidc/src/test/java/org/wildfly/security/http/oidc/KeycloakConfiguration.java
@@ -75,6 +75,7 @@ public class KeycloakConfiguration {
public static final String A192CBC_HS384 = "A192CBC-HS384";
public static final String A256CBC_HS512 = "A256CBC-HS512";
public static CAGenerationTool caGenerationTool = null;
+ public X509Certificate caCertificate = null;
// the users below are for multi-tenancy tests specifically
public static final String TENANT1_USER = "tenant1_user";
@@ -227,11 +228,6 @@ private static ClientRepresentation createWebAppClient(String clientId, String c
return createWebAppClient(clientId, clientSecret, clientHostName, clientPort, clientApp, directAccessGrantEnabled, null, multiTenancyApp);
}
- private static ClientRepresentation createWebAppClient(String clientId, String clientSecret, String clientHostName, int clientPort,
- String clientApp, boolean directAccessGrantEnabled, String allowedOrigin) throws Exception {
- return createWebAppClient(clientId, clientSecret, clientHostName, clientPort, clientApp, directAccessGrantEnabled, allowedOrigin, false);
- }
-
private static ClientRepresentation createWebAppClient(String clientId, String clientSecret, String clientHostName, int clientPort,
String clientApp, boolean directAccessGrantEnabled, String allowedOrigin, boolean multiTenancyApp) throws Exception {
ClientRepresentation client = new ClientRepresentation();
@@ -250,16 +246,18 @@ private static ClientRepresentation createWebAppClient(String clientId, String c
if (allowedOrigin != null) {
client.setWebOrigins(Collections.singletonList(allowedOrigin));
}
- OIDCAdvancedConfigWrapper oidcAdvancedConfigWrapper = OIDCAdvancedConfigWrapper.fromClientRepresentation(client);
- oidcAdvancedConfigWrapper.setUseJwksUrl(false);
- KEYSTORE_CLASSPATH = Objects.requireNonNull(KeycloakConfiguration.class.getClassLoader().getResource("")).getPath();
- caGenerationTool = CAGenerationTool.builder()
- .setBaseDir(KEYSTORE_CLASSPATH)
- .setRequestIdentities(CAGenerationTool.Identity.values()) // Create all identities.
- .build();
- X500Principal principal = new X500Principal("OU=Elytron, O=Elytron, C=UK, ST=Elytron, CN=OcspResponder");
- X509Certificate rsaCert = caGenerationTool.createIdentity(KEYSTORE_ALIAS, principal, RSA_KEYSTORE_FILE_NAME, CAGenerationTool.Identity.CA);
- client.getAttributes().put("jwt.credential.certificate", Base64.getEncoder().encodeToString(rsaCert.getEncoded()));
+ if (KeycloakConfiguration.class.getClassLoader().getResource(RSA_KEYSTORE_FILE_NAME) == null) {
+ OIDCAdvancedConfigWrapper oidcAdvancedConfigWrapper = OIDCAdvancedConfigWrapper.fromClientRepresentation(client);
+ oidcAdvancedConfigWrapper.setUseJwksUrl(false);
+ KEYSTORE_CLASSPATH = Objects.requireNonNull(KeycloakConfiguration.class.getClassLoader().getResource("")).getPath();
+ caGenerationTool = CAGenerationTool.builder()
+ .setBaseDir(KEYSTORE_CLASSPATH)
+ .setRequestIdentities(CAGenerationTool.Identity.values()) // Create all identities.
+ .build();
+ X500Principal principal = new X500Principal("OU=Elytron, O=Elytron, C=UK, ST=Elytron, CN=OcspResponder");
+ X509Certificate rsaCert = caGenerationTool.createIdentity(KEYSTORE_ALIAS, principal, RSA_KEYSTORE_FILE_NAME, CAGenerationTool.Identity.CA);
+ client.getAttributes().put("jwt.credential.certificate", Base64.getEncoder().encodeToString(rsaCert.getEncoded()));
+ }
return client;
}
diff --git a/http/oidc/src/test/java/org/wildfly/security/http/oidc/OidcTest.java b/http/oidc/src/test/java/org/wildfly/security/http/oidc/OidcTest.java
index a5ff5561e2..244d75d536 100644
--- a/http/oidc/src/test/java/org/wildfly/security/http/oidc/OidcTest.java
+++ b/http/oidc/src/test/java/org/wildfly/security/http/oidc/OidcTest.java
@@ -58,7 +58,10 @@
import java.util.HashMap;
import java.util.Map;
+import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.WebClient;
+import com.gargoylesoftware.htmlunit.TextPage;
+import io.restassured.RestAssured;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.QueueDispatcher;
import org.apache.http.HttpStatus;
@@ -67,12 +70,6 @@
import org.junit.Test;
import org.wildfly.security.http.HttpServerAuthenticationMechanism;
-import com.gargoylesoftware.htmlunit.TextPage;
-import com.gargoylesoftware.htmlunit.WebClient;
-import com.gargoylesoftware.htmlunit.html.HtmlPage;
-
-import io.restassured.RestAssured;
-
/**
* Tests for the OpenID Connect authentication mechanism.
*
@@ -280,7 +277,7 @@ public void testOpenIDWithPsSignedAndRsaEncryptedRequest() throws Exception {
}
@Test
- public void testOpenIDWithInvalidSignAlgorithm() throws Exception {
+ public void testOpenIDWithInvalidSigningAlgorithm() throws Exception {
//RSNULL is a valid signature algorithm, but not one of the ones supported by keycloak
performAuthentication(getOidcConfigurationInputStreamWithRequestParameter(REQUEST_TYPE_REQUEST.getValue(), "RSNULL", RSA_OAEP_256, A256CBC_HS512, KEYSTORE_CLASSPATH + KeycloakConfiguration.RSA_KEYSTORE_FILE_NAME, KeycloakConfiguration.KEYSTORE_ALIAS, PKCS12_KEYSTORE_TYPE), KeycloakConfiguration.ALICE, KeycloakConfiguration.ALICE_PASSWORD,
true, HttpStatus.SC_MOVED_TEMPORARILY, getClientUrl(), CLIENT_PAGE_TEXT, true);
@@ -623,7 +620,7 @@ private void performAuthentication(InputStream oidcConfig, String username, Stri
mechanism.evaluateRequest(request);
} catch (Exception e) {
if (checkInvalidRequestAlgorithm) {
- assertTrue(e.getMessage().contains("java.io.IOException: ELY23058"));
+ assertTrue(e.getMessage().contains("ELY23063: Failed to create the authentication request with request or request_uri parameter."));
return; //Expected to get an exception and ignore the rest
} else {
throw e;