com.datastax.dse.driver.internal.core.auth.DseGssApiAuthProvider Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 com.datastax.dse.driver.internal.core.auth;
import com.datastax.dse.driver.api.core.auth.DseGssApiAuthProviderBase;
import com.datastax.dse.driver.api.core.config.DseDriverOption;
import com.datastax.oss.driver.api.core.auth.AuthProvider;
import com.datastax.oss.driver.api.core.config.DriverExecutionProfile;
import com.datastax.oss.driver.api.core.context.DriverContext;
import com.datastax.oss.driver.api.core.metadata.EndPoint;
import edu.umd.cs.findbugs.annotations.NonNull;
import java.util.Map;
import net.jcip.annotations.ThreadSafe;
/**
* {@link AuthProvider} that provides GSSAPI authenticator instances for clients to connect to DSE
* clusters secured with {@code DseAuthenticator}.
*
* To activate this provider an {@code auth-provider} section must be included in the driver
* configuration, for example:
*
*
* dse-java-driver {
* auth-provider {
* class = com.datastax.dse.driver.internal.core.auth.DseGssApiAuthProvider
* login-configuration {
* principal = "user principal here ex [email protected]"
* useKeyTab = "true"
* refreshKrb5Config = "true"
* keyTab = "Path to keytab file here"
* }
* }
* }
*
*
* Kerberos Authentication
*
* Keytab and ticket cache settings are specified using a standard JAAS configuration file. The
* location of the file can be set using the java.security.auth.login.config
system
* property or by adding a login.config.url.n
entry in the java.security
* properties file. Alternatively a login-configuration section can be included in the driver
* configuration.
*
* See the following documents for further details:
*
*
* - JAAS
* Login Configuration File;
*
- Krb5LoginModule
* options;
*
- JAAS
* Authentication Tutorial for more on JAAS in general.
*
*
* Authentication using ticket cache
*
* Run kinit
to obtain a ticket and populate the cache before connecting. JAAS config:
*
*
* DseClient {
* com.sun.security.auth.module.Krb5LoginModule required
* useTicketCache=true
* renewTGT=true;
* };
*
*
* Authentication using a keytab file
*
* To enable authentication using a keytab file, specify its location on disk. If your keytab
* contains more than one principal key, you should also specify which one to select. This
* information can also be specified in the driver config, under the login-configuration section.
*
*
* DseClient {
* com.sun.security.auth.module.Krb5LoginModule required
* useKeyTab=true
* keyTab="/path/to/file.keytab"
* principal="[email protected]";
* };
*
*
* Specifying SASL protocol name
*
* The SASL protocol name used by this auth provider defaults to "
* {@value #DEFAULT_SASL_SERVICE_NAME}
".
*
* Important: the SASL protocol name should match the username of the Kerberos
* service principal used by the DSE server. This information is specified in the dse.yaml file by
* the {@code service_principal} option under the kerberos_options
* section, and may vary from one DSE installation to another – especially if you installed
* DSE with an automated package installer.
*
*
For example, if your dse.yaml file contains the following:
*
*
{@code
* kerberos_options:
* ...
* service_principal: cassandra/[email protected]
* }
*
* The correct SASL protocol name to use when authenticating against this DSE server is "{@code
* cassandra}".
*
* Should you need to change the SASL protocol name, use one of the methods below:
*
*
* - Specify the service name in the driver config.
*
* dse-java-driver {
* auth-provider {
* class = com.datastax.dse.driver.internal.core.auth.DseGssApiAuthProvider
* service = "alternate"
* }
* }
*
* - Specify the service name with the {@code dse.sasl.service} system property when starting
* your application, e.g. {@code -Ddse.sasl.service=cassandra}.
*
*
* If a non-null SASL service name is provided to the aforementioned config, that name takes
* precedence over the contents of the {@code dse.sasl.service} system property.
*
* Should internal sasl properties need to be set such as qop. This can be accomplished by
* including a sasl-properties in the driver config, for example:
*
*
* dse-java-driver {
* auth-provider {
* class = com.datastax.dse.driver.internal.core.auth.DseGssApiAuthProvider
* sasl-properties {
* javax.security.sasl.qop = "auth-conf"
* }
* }
* }
*
*/
@ThreadSafe
public class DseGssApiAuthProvider extends DseGssApiAuthProviderBase {
private final DriverExecutionProfile config;
public DseGssApiAuthProvider(DriverContext context) {
super(context.getSessionName());
this.config = context.getConfig().getDefaultProfile();
}
@NonNull
@Override
protected GssApiOptions getOptions(
@NonNull EndPoint endPoint, @NonNull String serverAuthenticator) {
// A login configuration is always necessary, throw an exception if that option is missing.
AuthUtils.validateConfigPresent(
config,
DseGssApiAuthProvider.class.getName(),
endPoint,
DseDriverOption.AUTH_PROVIDER_LOGIN_CONFIGURATION);
GssApiOptions.Builder optionsBuilder = GssApiOptions.builder();
if (config.isDefined(DseDriverOption.AUTH_PROVIDER_AUTHORIZATION_ID)) {
optionsBuilder.withAuthorizationId(
config.getString(DseDriverOption.AUTH_PROVIDER_AUTHORIZATION_ID));
}
if (config.isDefined(DseDriverOption.AUTH_PROVIDER_SERVICE)) {
optionsBuilder.withSaslProtocol(config.getString(DseDriverOption.AUTH_PROVIDER_SERVICE));
}
if (config.isDefined(DseDriverOption.AUTH_PROVIDER_SASL_PROPERTIES)) {
for (Map.Entry entry :
config.getStringMap(DseDriverOption.AUTH_PROVIDER_SASL_PROPERTIES).entrySet()) {
optionsBuilder.addSaslProperty(entry.getKey(), entry.getValue());
}
}
Map loginConfigurationMap =
config.getStringMap(DseDriverOption.AUTH_PROVIDER_LOGIN_CONFIGURATION);
optionsBuilder.withLoginConfiguration(loginConfigurationMap);
return optionsBuilder.build();
}
}