Skip to content

Commit

Permalink
Add configuration to control whether to install BouncyCastle provider
Browse files Browse the repository at this point in the history
Signed-off-by: Marko Strukelj <[email protected]>
  • Loading branch information
mstruk committed Jan 16, 2020
1 parent b676a31 commit 9f97db8
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,7 @@ public boolean getValueAsBoolean(String key, boolean fallback) {

private boolean isTrue(String result) {
String val = result.toLowerCase(Locale.ENGLISH);
boolean tru = val.equals("true") || val.equals("yes") || val.equals("y") || val.equals("1");
if (true) {
if (val.equals("true") || val.equals("yes") || val.equals("y") || val.equals("1")) {
return true;
}
if (val.equals("false") || val.equals("no") || val.equals("n") || val.equals("0")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import javax.net.ssl.SSLSocketFactory;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.Provider;
import java.security.PublicKey;
import java.security.Security;
import java.util.Map;
Expand All @@ -33,19 +34,18 @@
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

import static io.strimzi.kafka.oauth.validator.TokenValidationException.Status;
import static org.keycloak.TokenVerifier.IS_ACTIVE;
import static org.keycloak.TokenVerifier.SUBJECT_EXISTS_CHECK;

public class JWTSignatureValidator implements TokenValidator {

static {
Security.insertProviderAt(new BouncyCastleProvider(), 1);
}

private static final Logger log = LoggerFactory.getLogger(JWTSignatureValidator.class);

private static AtomicBoolean bouncyInstalled = new AtomicBoolean(false);

private final ScheduledExecutorService scheduler;

private final URI keysUri;
Expand All @@ -70,7 +70,9 @@ public JWTSignatureValidator(String keysEndpointUri,
int expirySeconds,
boolean defaultChecks,
boolean skipTypeCheck,
String audience) {
String audience,
boolean enableBouncyCastleProvider,
int bouncyCastleProviderPosition) {

if (keysEndpointUri == null) {
throw new IllegalArgumentException("keysEndpointUri == null");
Expand Down Expand Up @@ -105,6 +107,20 @@ public JWTSignatureValidator(String keysEndpointUri,
this.skipTypeCheck = skipTypeCheck;
this.audience = audience;

if (enableBouncyCastleProvider && !bouncyInstalled.getAndSet(true)) {
int installedPosition = Security.insertProviderAt(new BouncyCastleProvider(), bouncyCastleProviderPosition);
log.info("BouncyCastle security provider installed at position: " + installedPosition);

if (log.isDebugEnabled()) {
StringBuilder sb = new StringBuilder("Installed security providers:\n");
for (Provider p: Security.getProviders()) {
sb.append(" - " + p.toString() + " [" + p.getClass().getName() + "]\n");
sb.append(" " + p.getInfo() + "\n");
}
log.debug(sb.toString());
}
}

fetchKeys();

// set up periodic timer to update keys from server every refreshSeconds;
Expand All @@ -119,7 +135,9 @@ public JWTSignatureValidator(String keysEndpointUri,
+ "\n validIssuerUri: " + validIssuerUri
+ "\n certsRefreshSeconds: " + refreshSeconds
+ "\n certsExpirySeconds: " + expirySeconds
+ "\n skipTypeCheck: " + skipTypeCheck);
+ "\n skipTypeCheck: " + skipTypeCheck
+ "\n enableBouncyCastleProvider: " + enableBouncyCastleProvider
+ "\n bouncyCastleProviderPosition: " + bouncyCastleProviderPosition);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,10 @@ public void configure(Map<String, ?> configs, String saslMechanism, List<AppConf
throw new IllegalArgumentException("Exactly one jaasConfigEntry expected (size: " + jaasConfigEntries.size());
}

for (AppConfigurationEntry e: jaasConfigEntries) {
Properties p = new Properties();
p.putAll(e.getOptions());
config = new ServerConfig(p);
break;
}
AppConfigurationEntry e = jaasConfigEntries.get(0);
Properties p = new Properties();
p.putAll(e.getOptions());
config = new ServerConfig(p);

notJWT = config.getValueAsBoolean(Config.OAUTH_TOKENS_NOT_JWT, false);

Expand All @@ -79,6 +77,9 @@ public void configure(Map<String, ?> configs, String saslMechanism, List<AppConf

String jwksUri = config.getValue(ServerConfig.OAUTH_JWKS_ENDPOINT_URI);

boolean enableBouncy = config.getValueAsBoolean(ServerConfig.OAUTH_CRYPTO_BOUNCYCASTLE_PROVIDER_ENABLE, false);
int bouncyPosition = config.getValueAsInt(ServerConfig.OAUTH_CRYPTO_BOUNCYCASTLE_PROVIDER_POSITION, 0);

if (jwksUri != null) {
validator = new JWTSignatureValidator(
config.getValue(ServerConfig.OAUTH_JWKS_ENDPOINT_URI),
Expand All @@ -89,7 +90,9 @@ public void configure(Map<String, ?> configs, String saslMechanism, List<AppConf
config.getValueAsInt(ServerConfig.OAUTH_JWKS_EXPIRY_SECONDS, 360),
true,
config.getValueAsBoolean(ServerConfig.OAUTH_VALIDATION_SKIP_TYPE_CHECK, false),
null
null,
enableBouncy,
bouncyPosition
);
} else {
validator = new OAuthIntrospectionValidator(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ public class ServerConfig extends Config {
public static final String OAUTH_VALID_ISSUER_URI = "oauth.valid.issuer.uri";
public static final String OAUTH_INTROSPECTION_ENDPOINT_URI = "oauth.introspection.endpoint.uri";
public static final String OAUTH_VALIDATION_SKIP_TYPE_CHECK = "oauth.validation.skip.type.check";
public static final String OAUTH_CRYPTO_BOUNCYCASTLE_PROVIDER_ENABLE = "oauth.crypto.bouncycastle.provider.enable";
public static final String OAUTH_CRYPTO_BOUNCYCASTLE_PROVIDER_POSITION = "oauth.crypto.bouncycastle.provider.position";

public ServerConfig() {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ services:
# Validation config
- OAUTH_VALID_ISSUER_URI=http://${KEYCLOAK_HOST:-keycloak}:8080/auth/realms/${REALM:-demo-ec}
- OAUTH_JWKS_ENDPOINT_URI=http://${KEYCLOAK_HOST:-keycloak}:8080/auth/realms/${REALM:-demo-ec}/protocol/openid-connect/certs
- OAUTH_CRYPTO_BOUNCYCASTLE_PROVIDER_ENABLE=false

# username extraction from JWT token claim
- OAUTH_USERNAME_CLAIM=preferred_username
Expand Down

0 comments on commit 9f97db8

Please sign in to comment.