@@ -535,6 +535,231 @@ public AuthResponse loginByLDAP(final String username, final String password, fi
535535 return loginByUserPass (username , password , mount );
536536 }
537537
538+ /**
539+ * <p>Basic login operation to authenticate to a AWS backend using EC2 authentication. Example usage:</p>
540+ *
541+ * <blockquote>
542+ * <pre>{@code
543+ * final AuthResponse response = vault.auth().loginByAwsEc2("my-role", "identity", "signature", "nonce", null);
544+ *
545+ * final String token = response.getAuthClientToken();
546+ * }</pre>
547+ * </blockquote>
548+ *
549+ * @param role Name of the role against which the login is being attempted. If role is not specified, then the login endpoint
550+ * looks for a role bearing the name of the AMI ID of the EC2 instance that is trying to login if using the ec2
551+ * auth method, or the "friendly name" (i.e., role name or username) of the IAM principal authenticated.
552+ * If a matching role is not found, login fails.
553+ * @param identity Base64 encoded EC2 instance identity document.
554+ * @param signature Base64 encoded SHA256 RSA signature of the instance identity document.
555+ * @param nonce Client nonce used for authentication. If null, a new nonce will be generated by Vault
556+ * @return The auth token, with additional response metadata
557+ * @throws VaultException If any error occurs, or unexpected response received from Vault
558+ */
559+ public AuthResponse loginByAwsEc2 (final String role , final String identity , final String signature , final String nonce , final String awsAuthMount ) throws VaultException {
560+ int retryCount = 0 ;
561+
562+ final String mount = awsAuthMount != null ? awsAuthMount : "aws" ;
563+ while (true ) {
564+ try {
565+ // HTTP request to Vault
566+ final JsonObject request = Json .object ().add ("identity" , identity )
567+ .add ("signature" , signature );
568+ if (role != null ) {
569+ request .add ("role" , role );
570+ }
571+ if (nonce != null ) {
572+ request .add ("nonce" , nonce );
573+ }
574+ final String requestJson = request .toString ();
575+ final RestResponse restResponse = new Rest ()//NOPMD
576+ .url (config .getAddress () + "/v1/auth/" + mount + "/login" )
577+ .body (requestJson .getBytes ("UTF-8" ))
578+ .connectTimeoutSeconds (config .getOpenTimeout ())
579+ .readTimeoutSeconds (config .getReadTimeout ())
580+ .sslVerification (config .getSslConfig ().isVerify ())
581+ .sslContext (config .getSslConfig ().getSslContext ())
582+ .post ();
583+
584+ // Validate restResponse
585+ if (restResponse .getStatus () != 200 ) {
586+ throw new VaultException ("Vault responded with HTTP status code: " + restResponse .getStatus (), restResponse .getStatus ());
587+ }
588+ final String mimeType = restResponse .getMimeType () == null ? "null" : restResponse .getMimeType ();
589+ if (!mimeType .equals ("application/json" )) {
590+ throw new VaultException ("Vault responded with MIME type: " + mimeType , restResponse .getStatus ());
591+ }
592+ return new AuthResponse (restResponse , retryCount );
593+ } catch (Exception e ) {
594+ // If there are retries to perform, then pause for the configured interval and then execute the loop again...
595+ if (retryCount < config .getMaxRetries ()) {
596+ retryCount ++;
597+ try {
598+ final int retryIntervalMilliseconds = config .getRetryIntervalMilliseconds ();
599+ Thread .sleep (retryIntervalMilliseconds );
600+ } catch (InterruptedException e1 ) {
601+ e1 .printStackTrace ();
602+ }
603+ } else if (e instanceof VaultException ) {
604+ // ... otherwise, give up.
605+ throw (VaultException ) e ;
606+ } else {
607+ throw new VaultException (e );
608+ }
609+ }
610+ }
611+ }
612+
613+ /**
614+ * <p>Basic login operation to authenticate to a AWS backend using EC2 authentication. Example usage:</p>
615+ *
616+ * <blockquote>
617+ * <pre>{@code
618+ * final AuthResponse response = vault.auth().loginByAwsEc2("my-role", "pkcs7", "nonce", null);
619+ *
620+ * final String token = response.getAuthClientToken();
621+ * }</pre>
622+ * </blockquote>
623+ *
624+ * @param role Name of the role against which the login is being attempted. If role is not specified, then the login endpoint
625+ * looks for a role bearing the name of the AMI ID of the EC2 instance that is trying to login if using the ec2
626+ * auth method, or the "friendly name" (i.e., role name or username) of the IAM principal authenticated.
627+ * If a matching role is not found, login fails.
628+ * @param pkcs7 PKCS7 signature of the identity document with all \n characters removed.
629+ * @param nonce Client nonce used for authentication. If null, a new nonce will be generated by Vault
630+ * @return The auth token, with additional response metadata
631+ * @throws VaultException If any error occurs, or unexpected response received from Vault
632+ */
633+ public AuthResponse loginByAwsEc2 (final String role , final String pkcs7 , final String nonce , final String awsAuthMount ) throws VaultException {
634+ int retryCount = 0 ;
635+
636+ final String mount = awsAuthMount != null ? awsAuthMount : "aws" ;
637+ while (true ) {
638+ try {
639+ // HTTP request to Vault
640+ final JsonObject request = Json .object ().add ("pkcs7" , pkcs7 );
641+ if (role != null ) {
642+ request .add ("role" , role );
643+ }
644+ if (nonce != null ) {
645+ request .add ("nonce" , nonce );
646+ }
647+ final String requestJson = request .toString ();
648+ final RestResponse restResponse = new Rest ()//NOPMD
649+ .url (config .getAddress () + "/v1/auth/" + mount + "/login" )
650+ .body (requestJson .getBytes ("UTF-8" ))
651+ .connectTimeoutSeconds (config .getOpenTimeout ())
652+ .readTimeoutSeconds (config .getReadTimeout ())
653+ .sslVerification (config .getSslConfig ().isVerify ())
654+ .sslContext (config .getSslConfig ().getSslContext ())
655+ .post ();
656+
657+ // Validate restResponse
658+ if (restResponse .getStatus () != 200 ) {
659+ throw new VaultException ("Vault responded with HTTP status code: " + restResponse .getStatus (), restResponse .getStatus ());
660+ }
661+ final String mimeType = restResponse .getMimeType () == null ? "null" : restResponse .getMimeType ();
662+ if (!mimeType .equals ("application/json" )) {
663+ throw new VaultException ("Vault responded with MIME type: " + mimeType , restResponse .getStatus ());
664+ }
665+ return new AuthResponse (restResponse , retryCount );
666+ } catch (Exception e ) {
667+ // If there are retries to perform, then pause for the configured interval and then execute the loop again...
668+ if (retryCount < config .getMaxRetries ()) {
669+ retryCount ++;
670+ try {
671+ final int retryIntervalMilliseconds = config .getRetryIntervalMilliseconds ();
672+ Thread .sleep (retryIntervalMilliseconds );
673+ } catch (InterruptedException e1 ) {
674+ e1 .printStackTrace ();
675+ }
676+ } else if (e instanceof VaultException ) {
677+ // ... otherwise, give up.
678+ throw (VaultException ) e ;
679+ } else {
680+ throw new VaultException (e );
681+ }
682+ }
683+ }
684+ }
685+
686+ /**
687+ * <p>Basic login operation to authenticate to a AWS backend using IAM authentication. Example usage:</p>
688+ *
689+ * <blockquote>
690+ * <pre>{@code
691+ * final AuthResponse response = vault.auth().loginByAwsIam("my-role", "pkcs7", "nonce", null);
692+ *
693+ * final String token = response.getAuthClientToken();
694+ * }</pre>
695+ * </blockquote>
696+ *
697+ * @param role Name of the role against which the login is being attempted. If role is not specified, then the login endpoint
698+ * looks for a role bearing the name of the AMI ID of the EC2 instance that is trying to login if using the ec2
699+ * auth method, or the "friendly name" (i.e., role name or username) of the IAM principal authenticated.
700+ * If a matching role is not found, login fails.
701+ * @param iamRequestUrl PKCS7 signature of the identity document with all \n characters removed.Base64-encoded HTTP URL used in the signed request.
702+ * Most likely just aHR0cHM6Ly9zdHMuYW1hem9uYXdzLmNvbS8= (base64-encoding of https://sts.amazonaws.com/) as most requests will
703+ * probably use POST with an empty URI.
704+ * @param iamRequestBody Base64-encoded body of the signed request. Most likely QWN0aW9uPUdldENhbGxlcklkZW50aXR5JlZlcnNpb249MjAxMS0wNi0xNQ== which is
705+ * the base64 encoding of Action=GetCallerIdentity&Version=2011-06-15.
706+ * @param iamRequestHeaders
707+ * @return The auth token, with additional response metadata
708+ * @throws VaultException If any error occurs, or unexpected response received from Vault
709+ */
710+ public AuthResponse loginByAwsIam (final String role , final String iamRequestUrl , final String iamRequestBody , final String iamRequestHeaders , final String awsAuthMount ) throws VaultException {
711+ int retryCount = 0 ;
712+
713+ final String mount = awsAuthMount != null ? awsAuthMount : "aws" ;
714+ while (true ) {
715+ try {
716+ // HTTP request to Vault
717+ final JsonObject request = Json .object ().add ("iam_request_url" , iamRequestUrl )
718+ .add ("iam_request_body" , iamRequestBody )
719+ .add ("iam_request_headers" , iamRequestHeaders )
720+ .add ("iam_request_method" , "POST" );
721+ if (role != null ) {
722+ request .add ("role" , role );
723+ }
724+ final String requestJson = request .toString ();
725+ final RestResponse restResponse = new Rest ()//NOPMD
726+ .url (config .getAddress () + "/v1/auth/" + mount + "/login" )
727+ .body (requestJson .getBytes ("UTF-8" ))
728+ .connectTimeoutSeconds (config .getOpenTimeout ())
729+ .readTimeoutSeconds (config .getReadTimeout ())
730+ .sslVerification (config .getSslConfig ().isVerify ())
731+ .sslContext (config .getSslConfig ().getSslContext ())
732+ .post ();
733+
734+ // Validate restResponse
735+ if (restResponse .getStatus () != 200 ) {
736+ throw new VaultException ("Vault responded with HTTP status code: " + restResponse .getStatus (), restResponse .getStatus ());
737+ }
738+ final String mimeType = restResponse .getMimeType () == null ? "null" : restResponse .getMimeType ();
739+ if (!mimeType .equals ("application/json" )) {
740+ throw new VaultException ("Vault responded with MIME type: " + mimeType , restResponse .getStatus ());
741+ }
742+ return new AuthResponse (restResponse , retryCount );
743+ } catch (Exception e ) {
744+ // If there are retries to perform, then pause for the configured interval and then execute the loop again...
745+ if (retryCount < config .getMaxRetries ()) {
746+ retryCount ++;
747+ try {
748+ final int retryIntervalMilliseconds = config .getRetryIntervalMilliseconds ();
749+ Thread .sleep (retryIntervalMilliseconds );
750+ } catch (InterruptedException e1 ) {
751+ e1 .printStackTrace ();
752+ }
753+ } else if (e instanceof VaultException ) {
754+ // ... otherwise, give up.
755+ throw (VaultException ) e ;
756+ } else {
757+ throw new VaultException (e );
758+ }
759+ }
760+ }
761+ }
762+
538763 /**
539764 * <p>Basic login operation to authenticate to an github backend. Example usage:</p>
540765 *
0 commit comments