Using a Custom Credentials Provider for an Identity Provider
You can configure the connector to use a custom credentials provider class that obtains credentials from an identity provider. To do this, set the AwsCredentialsProviderClass
connection property to the FQCN of the credentials provider class, and set the AwsCredentialsProviderArguments
connection property to a comma-separated list of any String arguments necessary for the constructor of that credentials provider class.
For example, if you are using a credentials provider class named com.you.credential.provider.SampleSamlCredentialsProvider
and it requires String arguments named KEY_SAML_ASSERTION
and CUSTOM_PROVIDER_PERMISSIONS
, you would use the following connection URL to connect to Athena:
jdbc:awsathena://AwsRegion=us-east-1;AwsCredentialsProviderClass=com.you.credential.provider.SampleSamlCredentialsProvider;AwsCredentialsProviderArguments=KEY_SAML_ASSERTION,CUSTOM_PROVIDER_PERMISSIONS;
Creating a Custom Credentials Provider Class for an Identity Provider
To create a custom credentials provider class for an identity provider, do one of the following:
- Extend the
SamlCredentialsProvider
class provided by the connector to implement the procedures specific to your identity provider. Compared to the other implementations in this list, this one is more closely integrated with the connector implementation, and includes support for the relevant Simba Amazon Athena JDBC Connector connection properties (such asidp_host
,idp_port
,preferred_role
, andssl_insecure
). For more information, see Extending the SamlCredentialsProvider Class for an Identity Provider. - Implement the
com.simba.iamsupport.IPlugin
interface to define the methods for working with your identity provider. This implementation requires you to define all the methods for interacting with the identity provider. Additionally, it provides access to the connector's connection properties through theaddParameter()
method. For more information, see Implementing the com.simba.iamsupport.IPlugin Interface for an Identity Provider. - Define a class that extends the
com.simba.athena.amazonaws.auth.AWSCredentialsProvider
class to retrieve your AWS credentials from the provider. This implementation works similarly to the previous one in that it also requires you to define all the methods for interacting with the identity provider. However, this implementation does not support theaddParameter()
method. To pass in the parameters that the class requires, you must use theAwsCredentialsProviderArguments
connection property instead. For more information, see Extending the com.simba.athena.amazonaws.auth.AWSCredentialsProvider Class for an Identity Provider.
Extending the SamlCredentialsProvider Class for an Identity Provider
The Simba Amazon Athena JDBC Connector provides a class named SamlCredentialsProvider
. You can extend this class to implement the procedures for an identity provider using the SAML standard, so that the connector can authenticate connections using the credentials from the provider.
The exact procedure for implementing these procedures depends on the requirements specific to your identity provider. The following is a high-level overview of what a typical implementation might involve:
- Import the following libraries from the
com.simba.athena.iamsupport.plugin
package:java.io.IOException
com.simba.athena.iamsupport.plugin.SamlCredentialsProvider
If your implementation requires the
performPostSAMLAction()
method, then also import the following libraries:com.simba.athena.amazonaws.SdkClientException
com.simba.athena.iamsupport.model.CredentialsHolder
- Extend the
SamlCredentialsProvider
class, and include the following in your class definition: - A definition for each custom connection property that the provider requires.
- A field for specifying the values for these custom connection properties.
- Optionally, a default constructor.
- An override for the
addParameter()
method, to specify if-conditions that check for custom connection properties and implements the necessary behavior. At minimum, this override should include the parent class that provides support for all the connection properties that the Simba Amazon Athena JDBC Connector supports by default. - An override for the
getSamlAssertion()
method, to return the SAML assertion string from your provider to the connector. This enables the current class implementation to retrieve temporary credentials from the provider. - A post-SAML workflow hook to exchange any temporary credentials for proper AWS credentials. For more information, see Using the Post-SAML Workflow Hook.
The following code sample shows how this might be accomplished:
package com.simba.athena.iamsupport.plugin;
import java.io.IOException;
import com.simba.athena.iamsupport.plugin.SamlCredentialsProvider;
/**
* The following two imports are needed for the
* performPostSAMLAction() method.
* They are not needed if your implementation does not
* require this method.
*/
import com.simba.athena.amazonaws.SdkClientException;
import com.simba.athena.iamsupport.model.CredentialsHolder;
/**
* A basic SAML credentials provider class. This class can be
* changed and implemented to work with any desired SAML
* service provider.
*/
public class SampleSamlCredentialsProvider extends SamlCredentialsProvider
{
/**
* Here we are defining a new connection property key
* called "saml_assertion". This property is specific
* to the SampleSamlCredentialsProvider, and is used
* to provide some information through the connection
* URL.
* <p>
* For example, when using this credentials provider,
* you may include the following in the connection URL:
* <p>
* <code>
* jdbc:awsathena://AwsRegion=[Region];
* S3OutputLocation=[Output];saml_assertion=[Value]* </code>
* <p>
* If your implementation requires user input through
* the connection URL, you can define the key name of
* the property using the following code:
* <p>
* <code>
* public static final String PROPERTY_NAME =
* "key_name";* </code>
* <p>
* You can add as many new connection properties as
* needed.
* "key_name" is subject to the following restrictions:
* <p>
* - The name must be unique. It cannot match any
* existing connection property key name in the
* Simba Amazon Athena JDBC Connector. These key names are
* case-insensitive, so even if the case does not match
* what is found in the documentation, the key name is* not allowed.
* <p>
* - The key name cannot contain any spaces.
* <p>
* - The key name can only contain letters of the
* alphabet (upper-case and lower-case) or
* underscores (_).*
*/
public static final String KEY_SAML_ASSERTION = "saml_assertion";
/**
* This field stores the value given with the
* associated connection property key.
* <p>
* If you add more connection property keys, then you
* must define additional fields to hold those values.
*/
private String samlAssertion;
/**
* Optional default constructor.
*/
public SampleSamlCredentialsProvider()
{
}
/**
* This method is used to get the values associated
* with different connection string properties.
* <p>
* We override it in this custom credentials provider
* to add a check for any additional connection
* properties that were added, which are not included
* in the existing Athena JDBC connector. It allows us
* to store these values using the appropriate fields
* as mentioned above.
* <p>
* For any new connection property keys added to this
* class, add an if-condition to check if the current
* key matches the connection property key. If so,
* store the value associated with the key in the
* appropriate field.
* <p>
* If no new connection property keys are required, you
* may leave the implementation blank and simply return
* a call to the parent class implementation.
* <p>
* See the example below.
*
* @param key A string representing the connection
* property key.
* @param value The value associated with the
* connection property key.
*/
@Override
public void addParameter(String key, String value)
{
// The parent class takes care of setting up all the
// connection properties that are mentioned in the
// Simba Amazon Athena JDBC Connector documentation.
super.addParameter(key, value);
// Add if-condition checks for any connection
// properties which are specific to your
// implementation of this custom SAML credentials
// provider.
if (KEY_SAML_ASSERTION.equalsIgnoreCase(key))
{
samlAssertion = value;
}
}
/**
* This method needs to return the SAML assertion
* string returned by the specific SAML provider
* being used for this implementation. The exact
* instructions for getting this string vary
* depending on the specific SAML provider you
* are using.
* <p>
* This is used by the SamlCredentialsProvider parent
* class to get the temporary credentials.
*
* @return The SAML assertion string.
* @throws IOException
*/
@Override
protected String getSamlAssertion() throws IOException
{
/*
* If you wish to make a connection property required,
* you can check that the associated field has been
* populated, and if not, throw an IOException.
* if (StringUtils.isNullOrEmpty(samlAssertion))
* {
* throw new IOException("Missing required property: " + KEY_SAML_ASSERTION);
* }
*/
return samlAssertion;
}
/**
* This method is used to perform custom actions after
* temporary credentials become available.
* This method is only needed if your authentication
* workflow requires an additional step to turn
* temporary credentials into AWS credentials.
*
* The inputs are the temporary credentials returned by
* the provider, and a SAML assertion that determines
* how these credentials are exchanged for AWS
* credentials.
*
* @param username The user name.
* @param samlAssertion The SAML assertion.
* @param credentials The temporary credentials from
* the assumeRoleWithSAML request.
*
* @return The updated or new credentials from the
* post-SAML authentication action.
* If null is returned, this indicates that no
* post-SAML authentication action was performed and the
* existing credentials should not be updated.
*
* @throws SdkClientException The exception that
* occurred.
*/
protected CredentialsHolder performPostSAMLAction(
String username,
String samlAssertion,
CredentialsHolder credentials) throws SdkClientException
{
return null;
}
}
Implementing the com.simba.iamsupport.IPlugin Interface for an Identity Provider
You can define a custom class that implements the com.simba.iamsupport.IPlugin
interface to define the methods for working with an identity provider.
The exact procedure for doing this depends on the specific requirements for your identity provider. In general, you need to define all the methods for interacting with the identity provider. You also have the option of using the addParameter()
method to define custom connection properties.
The following example shows how to use addParameter()
:
/**
* This method is used to get the values associated with
* different connection string properties.
* <p>
* We override it in this custom credentials provider to
* add a check for any additional connection properties
* that were added, which are not included in the existing
* Athena JDBC connector. It allows us to store these values
* using the appropriate fields as mentioned above.
* <p>
* For any new connection property keys added to this
* class, add an if-condition to check for the following:
* if the current key matches the connection property key,
* store the value associated with the key in the
* appropriate field.
* <p>
* If no new connection property keys are required, you
* may leave the implementation blank and simply return
* a call to the parent class implementation.
* <p>
* See the example below.
*
* @param key A string representing the connection
* property key.
* @param value The value associated with the connection
* property key.
*/
@Override
public void addParameter(String key, String value)
{
// The parent class takes care of setting up all the
// connection properties that are mentioned in the Athena
// JDBC connector documentation.
super.addParameter(key, value);
// Add if-condition checks for any connection properties
// which are specific to your implementation of this
// custom SAML credentials provider.
if (KEY_SAML_ASSERTION.equalsIgnoreCase(key))
{
samlAssertion = value;
}
}
Extending the com.simba.athena.amazonaws.auth.AWSCredentialsProvider Class for an Identity Provider
You can extend the com.simba.athena.amazonaws.auth.AWSCredentialsProvider
class to retrieve AWS credentials from an identity provider.
The exact procedure for doing this depends on the specific requirements for your identity provider. In general, you need to define all the methods for interacting with the identity provider.
Be aware that you cannot use addParameter()
to define custom connection properties. Instead, you must use the AWSCredentialsProviderArguments
connection property to pass in all the parameters that this class requires. For more information about this property, see AwsCredentialsProviderClass.
For an example of a class that extends the com.simba.athena.amazonaws.auth.AWSCredentialsProvider
class and uses the AwsCredentialsProviderArguments
to pass in parameters, see Example: CustomSessionCredentialsProvider.