Code Monkey home page Code Monkey logo

aws-sigv4-auth-cassandra-java-driver-plugin's Introduction

IMPORTANT: Latest Version

The current version is 4.0.9. Please see the changelog for details on version history.

What

This package implements an authentication plugin for the open-source Datastax Java Driver for Apache Cassandra. The driver enables you to add authentication information to your API requests using the AWS Signature Version 4 Process (SigV4). Using the plugin, you can provide users and applications short-term credentials to access Amazon Keyspaces (for Apache Cassandra) using AWS Identity and Access Management (IAM) users and roles.

The plugin depends on the AWS SDK for Java. It uses AWSCredentialsProvider to obtain credentials. Because the IAuthenticator interface operates at the level of InetSocketAddress, you must specify the service endpoint to use for the connection. You can provide the Region in the constructor programmatically, via the AWS_REGION environment variable, or via the aws.region system property. You can also provide an IAM role to assume for access to KeySpaces, programmatically or via the configuration file.

The full documentation for the plugin is available at https://docs.aws.amazon.com/keyspaces/latest/devguide/programmatic.credentials.html#programmatic.credentials.SigV4_KEYSPACES.

Example Usage

For example code, see https://github.com/aws-samples/aws-sigv4-auth-cassandra-java-driver-examples.

Using the Plugin

The following sections describe how to use the authentication plugin for the open-source DataStax Java Driver for Cassandra to access Amazon Keyspaces.

SSL Configuration

The first step is to get an Amazon digital certificate to encrypt your connections using Transport Layer Security (TLS). The DataStax Java driver must use an SSL trust store so that the client SSL engine can validate the Amazon Keyspaces certificate on connection. To use the trust store and create a certificate, see Using a Cassandra Java Client Driver to Access Amazon Keyspaces Programmatically.

Region Configuration

Before you can start using the plugin, you must configure the AWS Region that the plugin will use when authenticating. This is required because SigV4 signatures are Region-specific. For example, if you are connecting to the cassandra.us-east-2.amazonaws.com endpoint, the Region must be us-east-2. For a list of available AWS Regions and endpoints, see Service Endpoints for Amazon Keyspaces.

You can specify the Region using one of the following four methods:

  • Environment Variable
  • System Property
  • Constructor
  • Configuration

Environment Variable

You can use the AWS_REGION environment variable to match the endpoint that you are communicating with by setting it as part of your application start-up, as follows.

$ export AWS_Region=us-east-1

System Property

You can use the aws.region Java system property by specifying it on the command line, as follows.

$ java -Daws.region=us=east-1 ...

Constructor

One of the constructors for software.aws.mcs.auth.SigV4AuthProvider takes a String representing the Region that will be used for that instance.

Configuration

Set the Region explicitly in your advanced.auth-provider configuration (see example below), by specifying the advanced.auth-provider.aws-region property.

Assume IAM Role Configuration

You can specify an IAM role to assume for access to KeySpaces using either the constructor or the driver configuration file

Constructor

One of the constructors for software.aws.mcs.auth.SigV4AuthProvider takes two Strings , the first representing the region and the second representing the ARN of the IAM role to assume.

Configuration

Set the IAM Role explicitly in your advanced.auth-provider configuration (see example below), by specifying the advanced.auth-provider.aws-role-arn property.

Add the Authentication Plugin to the Application

The authentication plugin supports version 4.x of the DataStax Java Driver for Cassandra.

With Maven/Ivy

If you’re using Apache Maven, or a build system that can use Maven dependencies, add the following dependencies to your pom.xml file.

<dependency>
    <groupId>software.aws.mcs</groupId>
    <artifactId>aws-sigv4-auth-cassandra-java-driver-plugin</artifactId>
    <version>4.0.6</version>
</dependency>

Download the Shaded JAR

If you just need the JAR to use with a third party tool, please use the shaded JAR (includes the SDK and other dependencies) located in the releases section on GitHub.

How to use the Authentication Plugin

When using the open-source DataStax Java driver, the connection to your Amazon Keyspaces endpoint is represented by the CqlSession class. To create the CqlSession, you can either configure it programmatically using the CqlSessionBuilder class (accessed via CqlSession.builder()) or with the configuration file.

Programmatically Configure the Driver

When using the DataStax Java driver, you interact with Amazon Keyspaces primarily through the CQLSession class. You can create an instance of CqlSession using the CqlSession.builder() function. CqlSession.builder() enables you to specify another authentication provider for the session by using the with withAuthProvider function.

To use the authentication plugin, you set a Region-specific instance of SigV4AuthProvider as the authentication provider, as in the following example.

  1. Call addContactPoints on the builder with a collection of java.net.InetSocketAddress instances corresponding to the endpoints for your Region. Contact points are the endpoints that the driver will connect to. For a full list of endpoints and Regions in the documentation, see Service Endpoints for Amazon Keyspaces.
  2. Add an SSL context by calling withSslContext on the builder. This uses the trust store defined previously to negotiate SSL on the connection to the endpoints. SSL is required for Amazon Keyspaces. Without this setting, connections will time out and fail.
  3. Set the local data center to the region name, in this example it is us-east-2. The local data center is used by the driver for routing of requests, and it is required when the builder is constructed with addContactPoints.
  4. Set the authentication provider to a new instance of software.aws.mcs.auth.SigV4AuthProvider. The SigV4AuthProvider is the authentication handler provided by the plugin for performing SigV4 authentication. You can specify the Region for the endpoints that you’re using in the constructor for SigV4AuthProvider, as in the following example. Or, you can set the environment variable or system property as shown previously.

The following code example demonstrates the previous steps.

    List<InetSocketAddress> contactPoints =
      Collections.singletonList(
       InetSocketAddress.createUnresolved("cassandra.us-east-2.amazonaws.com", 9142));

    try (CqlSession session = CqlSession.builder()
      .addContactPoints(contactPoints)
      .withSslContext(SSLContext.getDefault())
      .withLocalDatacenter("us-east-2")
      .withAuthProvider(new SigV4AuthProvider("us-east-2"))
      .build()) {
      // App code here...
    }

Use a Configuration File

To use the configuration file, set the advanced.auth-provider.class to software.aws.mcs.auth.SigV4AuthProvider. You can also set the region, local data center and enable SSL in the configuration.

  1. Set the advanced.auth-provider.class to software.aws.mcs.auth.SigV4AuthProvider.
  2. Set basic.load-balancing-policy.local-datacenter to the region name. In this case, use us-east-2.

The following is an example of this config without explicit role to be assumed.

    datastax-java-driver {
        basic.load-balancing-policy {
            class = DefaultLoadBalancingPolicy
            local-datacenter = us-east-2
        }
        advanced {
            auth-provider = {
                class = software.aws.mcs.auth.SigV4AuthProvider
                aws-region = us-east-2
            }
            ssl-engine-factory {
                class = DefaultSslEngineFactory
            }
        }
    }

The following is an example of this config with an explicit role to be assumed.

    datastax-java-driver {
        basic.load-balancing-policy {
            class = DefaultLoadBalancingPolicy
            local-datacenter = us-east-2
        }
        advanced {
            auth-provider = {
                class = software.aws.mcs.auth.SigV4AuthProvider
                aws-region = us-east-2
                aws-role-arn = "arn:aws:iam::ACCOUNT_ID:role/ROLE_NAME"
            }
            ssl-engine-factory {
                class = DefaultSslEngineFactory
            }
        }
    }

aws-sigv4-auth-cassandra-java-driver-plugin's People

Contributors

akshayar avatar amazon-auto avatar bhouse99 avatar dchenbec avatar dependabot[bot] avatar erihuan avatar krjiang avatar michaelraney avatar pranayw333 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

aws-sigv4-auth-cassandra-java-driver-plugin's Issues

C# Driver

I don't know if this is the right place to ask. However, I have been trying to put together the code to connect to managed Cassandra instance with little luck. Will something like this driver but for c# be required to connect to mcs using roles and federated entities? I think I can use username and password but it doesn't look like that is the correct way to do it. However, I don't think a c# driver for SigV4AuthProvider exists yet. Right?

Generating invalid signatures on Windows platforms

The method generateSignature generates an invalid stringToSign on Windows platforms.

It uses the String.format, using %n as line separators which corresponds to the OS line separator. In Windows, that is \r\n, but according to the specs, the line separator must be \n.

The same also applies in the method canonicalizeRequest.

Version 4.0.3 not compatible with other AWS libraries ( Ex: version 1.11.904 )

This version requires

        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-core</artifactId>
            <version>1.11.717</version>
        </dependency>

which is incompatible with newest com.amazonaws library releases

java.lang.NoSuchFieldError: ENDPOINT_OVERRIDDEN
	at com.amazonaws.services.sqs.AmazonSQSClient.executeGetQueueUrl(AmazonSQSClient.java:1200) ~[aws-java-sdk-sqs-1.11.904.jar:?]
	at com.amazonaws.services.sqs.AmazonSQSClient.getQueueUrl(AmazonSQSClient.java:1182) ~[aws-java-sdk-sqs-1.11.904.jar:?]
	at com.amazon.sqs.javamessaging.AmazonSQSMessagingClientWrapper.queueExists(AmazonSQSMessagingClientWrapper.java:220) ~[amazon-sqs-java-messaging-lib-1.0.8.jar:?]

Problem with OpenJDK "14.0.1"

Having this exception when trying to use this plugin with OpenJDK "14.0.1". Is there support for Java versions higher than 8?
I'm trying the sample of usage from AWS documentation here https://docs.aws.amazon.com/keyspaces/latest/devguide/programmatic.credentials.html

java.lang.NoClassDefFoundError: Could not initialize class org.codehaus.groovy.vmplugin.v7.Java7
	at org.codehaus.groovy.vmplugin.VMPluginFactory.<clinit>(VMPluginFactory.java:43)
	at org.codehaus.groovy.reflection.GroovyClassValueFactory.<clinit>(GroovyClassValueFactory.java:35)
	at org.codehaus.groovy.reflection.ClassInfo.<clinit>(ClassInfo.java:107)
	at org.codehaus.groovy.reflection.ReflectionCache.getCachedClass(ReflectionCache.java:95)
	at org.codehaus.groovy.reflection.ReflectionCache.<clinit>(ReflectionCache.java:39)
	at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.registerMethods(MetaClassRegistryImpl.java:209)
	at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.<init>(MetaClassRegistryImpl.java:107)
	at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.<init>(MetaClassRegistryImpl.java:85)
	at groovy.lang.GroovySystem.<clinit>(GroovySystem.java:36)
	at java.base/java.lang.Class.forName0(Native Method)
	at java.base/java.lang.Class.forName(Class.java:340)
	at com.amazonaws.util.VersionInfoUtils.languageVersion(VersionInfoUtils.java:281)
	at com.amazonaws.util.VersionInfoUtils.groovyVersion(VersionInfoUtils.java:208)
	at com.amazonaws.util.VersionInfoUtils.getAdditionalJvmLanguages(VersionInfoUtils.java:192)
	at com.amazonaws.util.VersionInfoUtils.userAgent(VersionInfoUtils.java:161)
	at com.amazonaws.util.VersionInfoUtils.initializeUserAgent(VersionInfoUtils.java:137)
	at com.amazonaws.util.VersionInfoUtils.getUserAgent(VersionInfoUtils.java:100)
	at com.amazonaws.internal.EC2ResourceFetcher.<clinit>(EC2ResourceFetcher.java:44)
	at com.amazonaws.auth.InstanceMetadataServiceCredentialsFetcher.<init>(InstanceMetadataServiceCredentialsFetcher.java:36)
	at com.amazonaws.auth.InstanceProfileCredentialsProvider.<init>(InstanceProfileCredentialsProvider.java:102)
	at com.amazonaws.auth.InstanceProfileCredentialsProvider.<init>(InstanceProfileCredentialsProvider.java:82)
	at com.amazonaws.auth.InstanceProfileCredentialsProvider.<init>(InstanceProfileCredentialsProvider.java:66)
	at com.amazonaws.auth.InstanceProfileCredentialsProvider.<clinit>(InstanceProfileCredentialsProvider.java:49)
	at com.amazonaws.auth.EC2ContainerCredentialsProviderWrapper.initializeProvider(EC2ContainerCredentialsProviderWrapper.java:64)
	at com.amazonaws.auth.EC2ContainerCredentialsProviderWrapper.<init>(EC2ContainerCredentialsProviderWrapper.java:53)
	at com.amazonaws.auth.DefaultAWSCredentialsProviderChain.<init>(DefaultAWSCredentialsProviderChain.java:48)
	at com.amazonaws.auth.DefaultAWSCredentialsProviderChain.<clinit>(DefaultAWSCredentialsProviderChain.java:42)
	at software.aws.mcs.auth.SigV4AuthProvider.<init>(SigV4AuthProvider.java:102)
	at io.ninety.config.CassandraSession.session(CassandraSession.java:47)
	at io.ninety.ShipDataServiceApp.main(ShipDataServiceApp.java:33)
Exception in thread "main" java.lang.NoClassDefFoundError: Could not initialize class org.codehaus.groovy.reflection.ReflectionCache
	at org.codehaus.groovy.runtime.dgmimpl.NumberNumberMetaMethod.<clinit>(NumberNumberMetaMethod.java:33)
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500)
	at java.base/java.lang.reflect.ReflectAccess.newInstance(ReflectAccess.java:124)
	at java.base/jdk.internal.reflect.ReflectionFactory.newInstance(ReflectionFactory.java:346)
	at java.base/java.lang.Class.newInstance(Class.java:604)
	at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.createMetaMethodFromClass(MetaClassRegistryImpl.java:257)
	at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.<init>(MetaClassRegistryImpl.java:110)
	at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.<init>(MetaClassRegistryImpl.java:85)
	at groovy.lang.GroovySystem.<clinit>(GroovySystem.java:36)
	at java.base/java.lang.Class.forName0(Native Method)
	at java.base/java.lang.Class.forName(Class.java:340)
	at com.amazonaws.util.VersionInfoUtils.languageVersion(VersionInfoUtils.java:281)
	at com.amazonaws.util.VersionInfoUtils.groovyVersion(VersionInfoUtils.java:208)
	at com.amazonaws.util.VersionInfoUtils.getAdditionalJvmLanguages(VersionInfoUtils.java:192)
	at com.amazonaws.util.VersionInfoUtils.userAgent(VersionInfoUtils.java:161)
	at com.amazonaws.util.VersionInfoUtils.initializeUserAgent(VersionInfoUtils.java:137)
	at com.amazonaws.util.VersionInfoUtils.getUserAgent(VersionInfoUtils.java:100)
	at com.amazonaws.internal.EC2ResourceFetcher.<clinit>(EC2ResourceFetcher.java:44)
	at com.amazonaws.auth.InstanceMetadataServiceCredentialsFetcher.<init>(InstanceMetadataServiceCredentialsFetcher.java:36)
	at com.amazonaws.auth.InstanceProfileCredentialsProvider.<init>(InstanceProfileCredentialsProvider.java:102)
	at com.amazonaws.auth.InstanceProfileCredentialsProvider.<init>(InstanceProfileCredentialsProvider.java:82)
	at com.amazonaws.auth.InstanceProfileCredentialsProvider.<init>(InstanceProfileCredentialsProvider.java:66)
	at com.amazonaws.auth.InstanceProfileCredentialsProvider.<clinit>(InstanceProfileCredentialsProvider.java:49)
	at com.amazonaws.auth.EC2ContainerCredentialsProviderWrapper.initializeProvider(EC2ContainerCredentialsProviderWrapper.java:64)
	at com.amazonaws.auth.EC2ContainerCredentialsProviderWrapper.<init>(EC2ContainerCredentialsProviderWrapper.java:53)
	at com.amazonaws.auth.DefaultAWSCredentialsProviderChain.<init>(DefaultAWSCredentialsProviderChain.java:48)
	at com.amazonaws.auth.DefaultAWSCredentialsProviderChain.<clinit>(DefaultAWSCredentialsProviderChain.java:42)
	at software.aws.mcs.auth.SigV4AuthProvider.<init>(SigV4AuthProvider.java:102)
	at io.ninety.config.CassandraSession.session(CassandraSession.java:47)
	at io.ninety.ShipDataServiceApp.main(ShipDataServiceApp.java:33)

DefaultTopologyMonitor and DefaultTokenFactoryRegistry Warning

We have moved our cassandra cluster to Amazon Keyspaces, in practice we did not face critical issues so far. But there's an already open discussion for DefaultTopologyMonitor and TokenFactory warnings. We have facing issues related to these warnings when we attempted to use in production.

  • Control node .../...:9142 has an entry for itself
  • Unsupported partitioner 'com.amazonaws.cassandra.DefaultPartitioner', token map will be empty.

We have following configuration as it's suggested by AWS experts in the discussion:

metadata { schema { enabled = false } token-map { enabled = false } }

The warnings are appearing after a period like ~24 hours without any action on our side. You can see the below chart, we have ~35k warnings coming from 10 different pods .

image

We are using AWS sigv4 plugin and we implemented as it's suggested in Sample Application

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.