This guide explains how an SAP ABAP program can generate presigned URLs for Amazon S3, allowing a third party temporary and secure access to an object in an S3 bucket.
Amazon S3 cloud storage provides an elastic, scalable and secure way to store business documents. Documents and data in S3 can be shared within an AWS account, and between AWS accounts, using granular permissions defined in IAM roles. The AWS SDK for SAP ABAP gives ABAP programmers a native way to consume S3 services using pure ABAP. If you’re new to the AWS SDK for SAP ABAP, check out our Getting Started page which describes installation, configuration, and includes your first Hello World program.
In some cases, it may be useful to share a document as a URL which can be viewed by the recipient who does not have their own credentials in AWS. Starting with the AWS SDK for SAP ABAP release v1.16.0, ABAP programs can presign an S3 URL so that the credentials are included in the URL itself. A user possessing the presigned URL can open the document with no further authentication required. Most importantly, the presigned URL expires after a preestablished interval. This makes presigned URLs extremely useful in scenarios where an SAP system needs to send a customer or partner a temporary link to a business document which should be valid for a limited period of time.
To use the ABAP presigner, create a session and an S3 client object as usual. The presigner can be retrieved from the S3 client object with /aws1/if_s3->get_presigner(). The presigner itself has methods such as getobject() and putobject(), which return presigned URLs which can be shared through a variety of channels. The signatures of the methods are nearly identical to the standard S3 client methods, but return a URL instead of actually performing the operation. For example, a typical retrieval of an S3 object looks like:
DATA(lo_results) = lo_s3->getobject(
iv_bucket = bucket
iv_key = lv_key ).
WRITE: / 'The S3 object contained: ', lo_results->get_body( ).
Generating a presigned URL for the same GetObject operation looks like:
DATA(lo_presigner) = lo_s3->get_presigner( iv_expires_sec = 300 ).
DATA(lo_presigned_req) = lo_presigner->getobject(
iv_bucket = bucket
iv_key = lv_key ).
WRITE: / 'The presigned URL is: ', lo_presigned_req->get_url( ).
The example ABAP report below uploads a document from the SAPGUI frontend, stores it in an S3 bucket, and writes the URL to the screen as a clickable link.
REPORT zaws1_s3_presigner_demo LINE-SIZE 1023.
PARAMETERS: sdk_pfl TYPE /aws1/rt_profile_id OBLIGATORY MEMORY ID awspfl.
PARAMETERS: bucket TYPE /aws1/s3_bucketname LOWER CASE OBLIGATORY MEMORY ID buk.
PARAMETERS: prefix TYPE /aws1/s3_objectkey LOWER CASE OBLIGATORY DEFAULT 'example-docs' .
PARAMETERS: exp_sec TYPE i DEFAULT 300 OBLIGATORY. " URL expires in 300 seconds
DATA: gv_url TYPE text2048.
START-OF-SELECTION.
TRY.
" establish the session with AWS and initialize the S3 client
" See the AWS documentation and transaction /AWS1/IMG for more on
" configuring an SDK profile
DATA(lo_session) = /aws1/cl_rt_session_aws=>create( sdk_pfl ).
DATA(lo_s3) = /aws1/cl_s3_factory=>create( io_session = lo_session ).
DATA(lo_presigner) = lo_s3->get_presigner( iv_expires_sec = exp_sec ).
" receive the file from the GUI, and put it into S3
DATA(ls_file) = cl_bcs_utilities=>upload( ).
DATA(lv_key) = |{ prefix }/{ ls_file-filename }|.
DATA(lv_mimetype) = cl_bcs_utilities=>get_mime_type( iv_name = ls_file-filename ).
lo_s3->putobject( iv_bucket = bucket
iv_key = lv_key
iv_body = ls_file-contents
iv_contenttype = CONV /aws1/s3_contenttype( lv_mimetype ) ).
" generate a presigned URL for getting the object from S3 and write it to the screen
DATA(lo_presigned_req) = lo_presigner->getobject( iv_bucket = bucket iv_key = lv_key ).
gv_url = lo_presigned_req->get_url( ).
WRITE: / gv_url HOTSPOT ON.
HIDE gv_url.
CATCH /aws1/cx_rt_generic INTO DATA(lo_ex).
WRITE: / lo_ex->get_text( ) COLOR COL_NEGATIVE.
ENDTRY.
" make the URL a clickable hyperlink
AT LINE-SELECTION.
cl_gui_frontend_services=>execute(
document = CONV string( gv_url )
operation = 'OPEN' ).
" error handling omitted for brevity
This example program is the starting point for a variety of useful functionality. An ABAP process could generate an invoice, upload it to S3, presign the URL and send it to customers via email with a 24 hour expiration. A report could be shared with a partner for a limited time. More exotic scenarios are possible, such as generating presigned URLs for PutObject operations to enable an external system to upload a data file to a predefined key. For more on presigned URLs in S3, see Sharing objects with presigned URLs.
#References
- AWS SDK for SAP ABAP - Getting Started
- Sharing objects with presigned URLs
- Create a presigned URL for Amazon S3 using an AWS SDK