Share Files Securely Over Internet Using AWS Cognito and S3

By September 25, 2019 November 22nd, 2019 AWS, Blogs

Written By: Priyanka Sharma, Cloud Architect, Powerupcloud Technologies

One of our clients requested a simple web app that can share files in a secure manner with internal and external users. Out-of-the-box solutions like Dropbox or Gladinet did not suffice their needs as the customer had more requirements for this web app. They are,

  • The web page should list the name and size of all the files stored in an S3 bucket.
  • The webpage should allow the user to select certain files and share them to any email address.
  • Their internal employees can view, upload and share the selected files whereas the external users can only view and share the selected files.
  • External users should not be allowed to upload any file to the S3 bucket.
  • On sharing, the recipient should get an email with the download link and post-authentication, the recipient should be able to download the files with that link.
  • The recipient should be able to download the file from the app console too.

Keeping these requirements in mind, we built a simple web application using which you can share the files securely among internal and external users.

In this post, we will take you through the way in which the application works.

Proposed Solution

The application was built with S3 as the primary storage repo. Following AWS services were also used in this application.

  • IAM Role: To assume after login.
  • IAM SAML Provider: With ADFS Federation Metadata.
  • S3 Bucket: To upload and share the files.
  • AWS Cognito User Pool: To create external users.
  • AWS Cognito Federated Identity Pool: For the authentication providers (SAML and Cognito User Pool).
  • AWS EC2 Ubuntu Server: The application code is kept and services through a web server.
  • AWS EC2 Windows Server: Managing Active Directory and ADFS for Internal Users.

Prerequisites

S3 Bucket

We created an S3 bucket with the name “private-Cognito-s3” with following CORS Configuration:

<?xml version="1.0" encoding="UTF-8"?> 
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

For Internal Users

IAM Role to Assume by the Users

Create an IAM Role with below trust relationship.

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Federated": "cognito-identity.amazonaws.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"cognito-identity.amazonaws.com:aud": "<cognito-federated-identity-pool-id>"
},
"ForAnyValue:StringLike": {
"cognito-identity.amazonaws.com:amr": "authenticated"
}
}
}
]
}

SAML Provider in AWS

Before you create a SAML provider, you need to download the SAML metadata document for your ADFS federation server. By default, you can download it from the following address:

https:///FederationMetadata/2007–06/FederationMetadata.xml

Create a SAML Provider in IAM with the above metadata file.

Setup ADFS

We followed the below link to set up a windows server for ADFS.

https://aws.amazon.com/blogs/security/enabling-federation-to-aws-using-windows-active-directory-adfs-and-saml-2-0/

Once we have the server provisioned, we created a relying party trust with the endpoints pointing to our application as shown in the below screenshot.

Also, we added the following Claim Rules for trust.

Transform

Get AD Groups With Rule

c:[Type == "http://schemas.micraosoft.com/ws/2008/06/identity/claims/windowsaccountname", Issuer == "AD AUTHORITY"]

=> add(store = "Active Directory", types = ("http://temp/variable"), query = ";tokenGroups;{0}", param = c.Value);

Roles

Provide the SAML Arn and Arn of the IAM Role to assume in the value.

=> issue(Type = "https://aws.amazon.com/SAML/Attributes/Role", Value = "arn:aws:iam::xxxxxxxx:saml-provider/cognito-s3-saml,arn:aws:iam::xxxxxxx:role/ADFS-Readonly");

RoleSessionName with Outgoing Claim Type

https://aws.amazon.com/SAML/Attributes/RoleSessionName

For External Users

Create Cognito User Pool

We have created a Cognito user pool with an app client “power app”.

Create Federated Identity Pool for SAML as well as Cognito User Pool. We created a Cognito Federated Identity Pool with authentication providers.

Cognito User Pool: Give user pool id and app client id

SAML: Select SAML Provider from the list

Implementation

We provisioned an Ubuntu Server and configured Nginx Web Server to serve the application. Refer to the application code in the repo below:

https://github.com/powerupcloud/aws-private-file-sharing-tool

Also, an API (code exists in API directory in the repo) has been used to authenticate and redirect the AD users to the correct page. Start the API using below command:

node server.js

The API starts listening on 8443 port.

Main Features of Application

  • The users will be able to view the contents of their particular bucket and a shared bucket. Users will not be able to access the buckets which are owned by other users.
  • The internal users i.e. AD Users will be able to view, upload and share the selected files to any user internally or externally.
  • The external users i.e. Cognito Users will be able to view and share the selected files to any user internally or externally.
  • After login, the user will get the temporary credentials so that he/she will be able to access the bucket.
  • After listing the existing files, the files can be downloaded from the same console by clicking on the file name.
  • Once a file is shared with a user, he/she will get a download link on his/her email address. Also, the file will get copied to his/her folder in the same S3 bucket. For example, if userA is sharing a fileA to userB (userb@gmail.com), the fileA will get copied to userB’s folder i.e. the structure of the bucket will be: s3bucket/userb@gmail.com/usera@gmail.com/fileA.
  • The download link will be sent to the email address.
  • If registered, the user will be asked to enter the credentials with MFA to download the file.
  • It not already registered, the user will be redirected to the registration page. Once registered, the user will be asked to reenter his/her credentials to download the file.

Application in Action: Internal Employees

Step 1: Hit the Application URL

Step 2: Enter the credentials of the AD User

Step 3: After successful login, the user will be redirected to the S3 page.

Note: we are having prefix value the same as the username. Hence, the bucket structure will be,

  • private-Cognito-s3
  • priyanka@puc.com/files
  • user1@puc.com/files
  • user2@gmail.com/files
  • shared/files

Step 4: Since we are logged in as priyanka@puc.com, we will be able to view the contents of the specified folder and won’t be able to view the content of other folders.

Step 5: We can select the files and share them to any email address.

Step 6: The email address is already registered in the AWS Cognito User Pool, hence the download link will ask for the login credentials to enter.

Step 7: After entering the credentials, it also asks for the code sent to the registered Mobile Number.

Step 8: After a successful login, the user will be able to download the file.

If the email is sent to an unregistered user, the workflow will be as shown in the below screenshots.

Step 9: The download link will redirect you to the registration page.

Step 10: Once registered, you need to enter your credentials on the next page.

Note: Even if someone got the download link, he/she wont be able to access the file. Since the file has been shared to a particular user, only that user can download the file by his/her credentials.

Step 11: After a successful login, you will be able to download the file.

Application in Action: External Employees

Step 1: Login as External Users

Step 2: After entering the credentials, you will be asked for the code sent to your Mobile Number

Step 3: After successful login, you will be redirected to the S3 page where you can view and share the files

Demo Video:

I hope you find this app useful in multiple scenarios. Happy File Sharing!! 🙂

References:

If you would like to know more details on this project or if you want us to build something similar for you, please write to us at cloud@powerupcloud.com.

Leave a Reply