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.
When using the function getPreSignedURLForS3, it is returning a singed URL starting with the domain name as below.
https://s3.{bucket-name}.amazonaws.com/
While my domain name for the S3 bucket in console is as below
https://{bucket-name}.s3.us-east-1.amazonaws.com/
Does anybody know, why the function returns the URL an incorrect format. I am passing the region parameter as "us-east-1". Or how can I fix/correct this?
Not sure if that is possible, you may got some help on S3 forums. Since the web api response is a redirect, the extra headers don't do anything.
Thank Mike ! I am able to download file now...but one more challenge i am facing is that I need to rename the file which is being getting download from presigned URL.I try to add extra header
Content-Disposition: attachment; filename="test.txt"But it is not workingAny suggestion ?
Why are you linking to an integration object? The link needs to be to the web api, otherwise the integration object runs and generates the link once - the web api never reevaluates again.
You need a link to the web api with a doc id as param, and a redirect and the URL in the Location header.
Some helpful background reading: en.wikipedia.org/.../HTTP_302
Mike Cichy jeank0002 baratc Iana Bakalova I am facing the same issue ,link is working fine for the first time but after that ,link is giving timeout error....I have generated presigned URL in web api and that web api is being called from interface in safelink .My requirement is to allow user to download document any number of time...link should be available all the time.Could you please help here. and code sample ?
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") )
Hi Mike,Thanks for responding so quickly. I am asking Appian Support about the stack trace. The plugin is on version 1.0.0.9 in two of our environments, both of which are on 22.2. It works in one environment, but is throwing the above error in the other.I will get more details on stack trace ASAP.
Do you have the stack trace? Was the environment upgraded?