Skip to content

Commit

Permalink
Migrate KerberosConfig to interface
Browse files Browse the repository at this point in the history
  • Loading branch information
gastaldi committed Jul 23, 2024
1 parent 500bacb commit 8262239
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@

import java.util.Optional;

import io.quarkus.runtime.annotations.ConfigItem;
import io.quarkus.runtime.annotations.ConfigPhase;
import io.quarkus.runtime.annotations.ConfigRoot;
import io.smallrye.config.ConfigMapping;
import io.smallrye.config.WithDefault;

@ConfigRoot(name = "kerberos", phase = ConfigPhase.RUN_TIME)
public class KerberosConfig {
@ConfigMapping(prefix = "quarkus.kerberos")
@ConfigRoot(phase = ConfigPhase.RUN_TIME)
public interface KerberosConfig {

/**
* JAAS Login context name.
Expand All @@ -19,53 +21,48 @@ public class KerberosConfig {
* Note this property will be ignored if a custom {@link io.quarkiverse.kerberos.ServicePrincipalSubjectFactory} is
* registered, and it creates a non-null service Subject for the current authentication request.
*/
@ConfigItem
public Optional<String> loginContextName;
Optional<String> loginContextName();

/**
* Specifies if a JAAS configuration 'debug' property should be enabled.
* Note this property is only effective when {@code loginContextName} is not set.
* and the JAAS configuration is created automatically.
*/
@ConfigItem(defaultValue = "false")
public boolean debug;
@WithDefault("false")
boolean debug();

/**
* Points to a service principal keytab file and will be used to set a JAAS configuration 'keyTab' property.
* Note this property is only effective when {@code loginContextName} is not set.
* and the JAAS configuration is created automatically.
*/
@ConfigItem
public Optional<String> keytabPath;
Optional<String> keytabPath();

/**
* Kerberos Service Principal Name.
* If this property is not set then the service principal name will be calculated by
* concatenating "HTTP/" and the HTTP Host header value, for example: "HTTP/localhost".
*/
@ConfigItem
public Optional<String> servicePrincipalName;
Optional<String> servicePrincipalName();

/**
* Kerberos Service Principal Realm Name.
* If this property is set then it will be added to the service principal name, for example,
* "HTTP/localhost@SERVICE-REALM.COM". Setting the realm property is not required if it matches
* a default realm set in the Kerberos Key Distribution Center (KDC) configuration.
*/
@ConfigItem
public Optional<String> servicePrincipalRealm;
Optional<String> servicePrincipalRealm();

/**
* Service principal password.
* Set this property only if using {@code keytabPath}, custom {@linkplain CallbackHandler} or
* {@linkplain ServicePrincipalSubjectFactory} is not possible.
*/
@ConfigItem
public Optional<String> servicePrincipalPassword;
Optional<String> servicePrincipalPassword();

/**
* Specifies whether to use Spnego or Kerberos OID.
*/
@ConfigItem(defaultValue = "true")
public boolean useSpnegoOid;
@WithDefault("true")
boolean useSpnegoOid();
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,18 +86,18 @@ public KerberosIdentityProvider(Instance<KerberosCallbackHandler> callbackHandle
throw new IllegalStateException("Multiple " + ServicePrincipalSubjectFactory.class + " beans registered");
}
String realKeytabPath = null;
if (kerberosConfig.keytabPath.isPresent()) {
URL keytabUrl = Thread.currentThread().getContextClassLoader().getResource(kerberosConfig.keytabPath.get());
if (kerberosConfig.keytabPath().isPresent()) {
URL keytabUrl = Thread.currentThread().getContextClassLoader().getResource(kerberosConfig.keytabPath().get());
if (keytabUrl != null) {
realKeytabPath = keytabUrl.toString();
} else {
Path filePath = Paths.get(kerberosConfig.keytabPath.get());
Path filePath = Paths.get(kerberosConfig.keytabPath().get());
if (Files.exists(filePath)) {
realKeytabPath = filePath.toAbsolutePath().toString();
}
}
if (realKeytabPath == null) {
throw new ConfigurationException("Keytab file is not available at " + kerberosConfig.keytabPath.get());
throw new ConfigurationException("Keytab file is not available at " + kerberosConfig.keytabPath().get());
}
}
this.realKeytabPath = realKeytabPath;
Expand Down Expand Up @@ -185,7 +185,7 @@ protected Subject getSubjectForServicePrincipal(String completeServicePrincipalN
}
}

String loginContextName = kerberosConfig.loginContextName.orElse(DEFAULT_LOGIN_CONTEXT_NAME);
String loginContextName = kerberosConfig.loginContextName().orElse(DEFAULT_LOGIN_CONTEXT_NAME);
Configuration config = DEFAULT_LOGIN_CONTEXT_NAME.equals(loginContextName)
? new DefaultJAASConfiguration(completeServicePrincipalName)
: null;
Expand All @@ -202,16 +202,16 @@ protected CallbackHandler getCallback(String completeServicePrincipalName) {
if (callbackHandler.isResolvable()) {
return callbackHandler.get();
}
if (kerberosConfig.servicePrincipalPassword.isPresent()) {
if (kerberosConfig.servicePrincipalPassword().isPresent()) {
return new UsernamePasswordCBH(completeServicePrincipalName,
kerberosConfig.servicePrincipalPassword.get().toCharArray());
kerberosConfig.servicePrincipalPassword().get().toCharArray());
}
return null;
}

protected GSSContext createGSSContext(RoutingContext routingContext, String completeServicePrincipalName)
throws GSSException {
Oid oid = new Oid(kerberosConfig.useSpnegoOid ? SPNEGO_OID : KERBEROS_OID);
Oid oid = new Oid(kerberosConfig.useSpnegoOid() ? SPNEGO_OID : KERBEROS_OID);

GSSManager gssManager = GSSManager.getInstance();
if (gssManager == null) {
Expand All @@ -223,15 +223,15 @@ protected GSSContext createGSSContext(RoutingContext routingContext, String comp
}

protected String getCompleteServicePrincipalName(RoutingContext routingContext) {
String name = kerberosConfig.servicePrincipalName.isEmpty()
String name = kerberosConfig.servicePrincipalName().isEmpty()
? "HTTP/" + routingContext.request().host()
: kerberosConfig.servicePrincipalName.get();
: kerberosConfig.servicePrincipalName().get();
int portIndex = name.indexOf(":");
if (portIndex > 0) {
name = name.substring(0, portIndex);
}
if (kerberosConfig.servicePrincipalRealm.isPresent()) {
name += "@" + kerberosConfig.servicePrincipalRealm.get();
if (kerberosConfig.servicePrincipalRealm().isPresent()) {
name += "@" + kerberosConfig.servicePrincipalRealm().get();
}
return name;
}
Expand Down Expand Up @@ -265,7 +265,7 @@ public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
// See https://docs.oracle.com/javase/8/docs/jre/api/security/jaas/spec/com/sun/security/auth/module/Krb5LoginModule.html
AppConfigurationEntry[] entries = new AppConfigurationEntry[1];
Map<String, Object> options = new HashMap<>();
if (kerberosConfig.debug) {
if (kerberosConfig.debug()) {
options.put("debug", "true");
}
options.put("refreshKrb5Config", "true");
Expand Down

0 comments on commit 8262239

Please sign in to comment.