Skip to content

Commit

Permalink
[squash] added changes for community stability level deployment
Browse files Browse the repository at this point in the history
  • Loading branch information
PrarthonaPaul committed Apr 12, 2024
1 parent 553ccb6 commit ab5f2a1
Show file tree
Hide file tree
Showing 15 changed files with 285 additions and 259 deletions.
Expand Up @@ -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;

Expand Down Expand Up @@ -236,19 +235,28 @@ interface ElytronMessages extends BasicLogger {
IOException noMessageEntity();

@Message(id = 23057, value = "Invalid keystore configuration for signing Request Objects.")
IOException invalidKeyStoreConfiguration();
RuntimeException invalidKeyStoreConfiguration();

@Message(id = 23058, value = "The signature algorithm specified is not supported by the OpenID Provider.")
IOException invalidRequestObjectSignatureAlgorithm();
@Message(id = 23058, value = "The request object signature algorithm specified is not supported by the OpenID Provider.")
RuntimeException invalidRequestObjectSignatureAlgorithm();

@Message(id = 23059, value = "The encryption algorithm specified is not supported by the OpenID Provider.")
IOException invalidRequestObjectEncryptionAlgorithm();
@Message(id = 23059, value = "The request object encryption algorithm specified is not supported by the OpenID Provider.")
RuntimeException invalidRequestObjectEncryptionAlgorithm();

@Message(id = 23060, value = "The content encryption algorithm specified is not supported by the OpenID Provider.")
IOException invalidRequestObjectContentEncryptionAlgorithm();
@Message(id = 23060, value = "The request object content encryption algorithm specified is not supported by the OpenID Provider.")
RuntimeException 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);
}

@@ -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");
Expand All @@ -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 <a href="mailto:prpaul@redhat.com">Prarthona Paul</a>
* */
public class JWKPublicKeySetExtractor implements OidcPublicKeyExtractor {
class JWKPublicKeySetExtractor implements PublicKeyLocator {
private Map<String, PublicKey> 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);
}
}

}
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
Expand Down

This file was deleted.

Expand Up @@ -35,18 +35,17 @@
* @author <a href="mailto:prpaul@redhat.com">Prarthona Paul</a>
*/

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);
Expand All @@ -55,8 +54,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
Expand Down
13 changes: 11 additions & 2 deletions http/oidc/src/main/java/org/wildfly/security/http/oidc/Oidc.java
Expand Up @@ -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";
Expand Down Expand Up @@ -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";
Expand Down Expand Up @@ -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;
Expand Down
Expand Up @@ -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() {
}
Expand Down Expand Up @@ -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() {
Expand All @@ -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() {
Expand All @@ -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;
}
}

0 comments on commit ab5f2a1

Please sign in to comment.