Overview
The Amazon S3 Utilities Plug-in leverages the Amazon AWS Java API to connect with Amazon S3 to store and retrieve files.
Key Features & Functionality
The following smart services are included:
The plug-in also includes a function:
Amazon S3 Utilities supports the following Amazon S3 features:
Note: The plug-in requires Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files when using client side encryption.
(https://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html)
The Appian Secure Credential Store is leveraged for the credentials to integrate with Amazon S3. Before executing the plug-in, create an new secure credential store with the following 3 attributes. These values are obtained from Amazon AWS IAM console.
Hello,
Is it possible to increase the expiration time? If we can have it as input that would be great; because due to Appian restrictions, we only have 5 seconds to generate a link and download the file.
Josh, what is the need for a custom timer? Is it for shortening or extending? Extending the expiration timer beyond a minimum opens up a security hole since the links can be shared and accessed by anyone. As explained in my previous response, the 5s timer is just to issue a redirect to the link once it's signed by AWS, which is more than long enough to do so (it could be argued it's too long still).
jeank0002, in case you or anyone else is interested, I used the getawsv4signature from the Cryptographic Hash Functions plugin to create a presigned S3 URL with a custom expiration value (a constant in our case). Here's the code I used:
if(a!isNullOrEmpty(ri!fileURI), null, a!localVariables( local!resourceURI: if(left(ri!fileURI, 1) = "/", ri!fileURI, "/"&ri!fileURI), local!currentTime: now(), local!dateTimeStamp: rule!TRSY_formatXAmzDateTime(dateTime: local!currentTime, isDateOnly: false), local!dateStamp: rule!TRSY_formatXAmzDateTime(dateTime: local!currentTime, isDateOnly: true), local!bucketName: cons!AWS_S3_PROFILE_IMAGE_BUCKET_NAME, local!hostname: local!bucketName & "." & cons!AWS_S3_DOMAIN_NAME, /* CredentialScope = <dateStamp>/<aws-region>/<aws-service>/aws4_request */ local!credentialScope: joinarray( { local!dateStamp, cons!AWS_S3_REGION, cons!AWS_S3_SERVICE_NAME, cons!AWS_SIGNATURE_VERSION }, "/" ), /* Query parameters */ local!amzParams: { a!map(param: "X-Amz-Algorithm", value: cons!AWS_SIGNING_ALGORITHM), a!map(param: "X-Amz-Credential", value: cons!AWS_S3_PROFILE_IMAGE_ACCESS_KEY_ID&"/"&local!credentialScope), a!map(param: "X-Amz-Date", value: local!dateTimeStamp), a!map(param: "X-Amz-Expires", value: cons!AWS_S3_PROFILE_IMAGE_PRESIGNED_URL_EXPIRATION_TIME), a!map(param: "X-Amz-SignedHeaders", value: "host") }, local!queryString: joinarray( a!forEach( items: local!amzParams, expression: urlencode(fv!item.param)&"="&urlencode(fv!item.value) ), "&" ), /* Step 1: Canonical request */ local!canonicalRequest: a!localVariables( local!headers: "host:"&local!hostname, joinarray( { "GET", local!resourceURI, local!queryString, local!headers&char(10), "host", "UNSIGNED-PAYLOAD" }, char(10) ) ), /* Step 2: String to sign */ local!stringToSign: joinarray( { cons!AWS_SIGNING_ALGORITHM, local!dateTimeStamp, local!credentialScope, sha256hash(local!canonicalRequest) }, char(10) ), /* Step 3: Signature */ local!signature: getawsv4signature( key:"", scsValue: { cons!AWS_S3_READONLY_PROFILE_IMAGE_SCSFIELD_EXTERNALFIELD, cons!AWS_S3_READONLY_PROFILE_IMAGE_SCSFIELD_FIELDNAME_SECRETACCESSKEY }, dateStamp: local!dateStamp, regionName: cons!TRSY_SQS_AWS_REGION, serviceName: cons!AWS_S3_SERVICE_NAME, string:local!stringToSign ), /* Return the full presigned URL */ "https://"&local!hostname&local!resourceURI&"?"&local!queryString&"&X-Amz-Signature="&local!signature ) )
And here's the code for the TRSY_formatXAmzDateTime rule:
if( or( a!isNullOrEmpty(ri!isDateOnly), not(ri!isDateOnly) ), text(gmt(ri!dateTime,"America/Chicago"), "yyyymmddThhmmss")&"Z", text(gmt(ri!dateTime,"America/Chicago"), "yyyymmdd") )
Will check it out, thank you!
Please see my instructions on plugin usage in a response form Jan 8, 2021. The 5 seconds is only needed to redirect the user to the pre-signed url and begin download. The download will continue as long as the connection is not interrupted.