Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate KerberosConfig to interface #127

Merged
merged 1 commit into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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