Generate AWS S3 Signed URL Using Java
What is Signed URL?
A signed URL is a temporary, secure link that grants access to a specific resource, such as a file or service, without requiring user authentication. It includes a cryptographic signature to ensure the link’s validity and integrity, making it a widely adopted solution for time-limited access. Signed URLs are particularly effective in scenarios where external users or systems need to interact with cloud resources securely, such as uploading files to storage, without exposing sensitive credentials or implementing complex authentication mechanisms.
In my use case, I needed a solution to enable users to upload files securely to an Amazon S3 bucket, with access restricted to a 5-minute validity period. This required a method that would ensure temporary, secure access without exposing sensitive credentials or requiring users to undergo complex authentication flows.
Several possible solutions were considered:
· Direct API Integration with Authentication: Involves using methods such as OAuth or API keys to grant controlled access to a service endpoint. This provides fine-grained access control but increases complexity.
· Custom Proxy Server: A server can act as an intermediary to validate and forward requests to cloud storage. This offers more control but adds latency and requires additional infrastructure.
· Server-Side Upload Handling: Users upload files to a backend server, which subsequently forwards the data to cloud storage. While this ensures full control, it consumes server resources and bandwidth.
After evaluating these options, I selected Amazon S3 with signed URLs due to its robust security, scalability, and simplicity.
Features of Signed URLs :
· Temporary Access: Signed URLs are valid for a limited duration, which can be defined when generating the URL. Example: A file upload system may use signed URLs to let users upload documents securely to cloud storage within a 5-minute validity window.
· Cryptographic Signature: The URL includes a hash-based signature, which ensures that the URL hasn’t been tampered with. Example: An application allows clients to upload compliance-related documents directly to cloud storage, with the signature verifying the authenticity of the request.
· Access Control: Signed URLs can be configured to provide access to specific files or resources and may allow certain operations like reading, writing, or deleting. Example: In a file-sharing service, clients can use signed URLs to upload documents directly to cloud storage without granting them full administrative access to the storage bucket.
· No Authentication Required: Users accessing the resource through a signed URL do not need direct credentials. Example: A workflow automation tool generates signed URLs to let third-party services upload files, avoiding the need to store or manage access keys.
How to generate AWS S3 signed URL Using Java?
- We will start by adding aws s3 dependency in your spring boot project:
2. After adding dependency, create a configuration file to read Region and Bucket name of s3 for which you want to create signed URL:
3. To generate the URL, we use:
· MessageDigest: A Java class to create a fixed-length hash for checking data integrity. Here we are using MessageDigest for calculating an MD5 hash of the file content
· PutObjectRequest: A class in the AWS SDK to define details for uploading files to an S3 bucket, like the bucket name and file path.
· S3Presigner: A class in the AWS SDK to create presigned URLs, allowing temporary and secure access to S3 objects without needing direct authentication.
The code generates a presigned URL for securely uploading a file to an Amazon S3 bucket. It combines the folder structure and file name to define the upload path and calculates a Base64-encoded MD5 hash for a Content-MD5 header to ensure file integrity. A PutObjectRequest is created with the bucket name, upload path, and metadata, and a PutObjectPresignRequest is used to define the URL’s expiration time. Using an S3Presigner, the presigned URL is generated and returned.
4. Now, Generate MD5 hash to pass in the Api using below mentioned command :
openssl dgst -md5 -binary {filename} | base64
5. Use this generate hash to pass in API to generate Signed URL and you will be getting a signed URL in the response:
6. Use that Signed URl and make a curl to upload the actual file to the S3 Bucket. you need to include Content-MD5, Content-Type header, and the same file in the form of binary:
Conclusion
In conclusion, the above-described method enables us to generate an AWS S3 signed URL using Java involves configuring the AWS SDK in a Spring Boot project, using PutObjectRequest and S3Presigner to create a secure, temporary URL for file uploads. The URL includes a cryptographic signature to ensure data integrity and access control. After generating an MD5 hash for the Content-MD5 header, the signed URL is used to upload a file to S3 with the necessary headers. This allows secure, time-limited access to S3 resources without direct authentication.