简体   繁体   中英

Send Signature to AWS JS SDK from server, instead of using plain text secret key

Is there a way to send signed version of secret key to AWS JS SDK , instead of sending secret Key adn access key in plain text. I am using Salesforce and would like to create a signature in Salesforce and send it to Javascript (or VF page) the signature which can then be used in AWS SDK callouts, instead of giving the secret key on the client side.

It's good that you see the obvious problem with embedding your credentials into the client.

Amazon Security Token Service (STS) is one solution to this issue.

Your application back-end systems send a request for temporary credentials to STS. These credentials allow the entity possessing them to perform only actions authorized by the token, which is a third attribute added to the usual (access key id, access key secret) tuple, and the authority is valid only until the token expires. Note that the token doesn't use your access key and secret, it actually comes with its own access key and secret, all of which are short-lived and "disposable."

In a sense, this is fairly well described by the phrase you used, "send signed version of secret key." It's a disposable delegation of authority, in a sense.

See also http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html .

I am finally able to make a call to STS from Salesforce using Apex Code, all thanks to Michael. Which then returns the Session Token, Temp Access Key and Temp Secret Key. Following is the gist of the code that I used to make a call to AWS STS.


public void  testGetSessionToken() { 
        method = HttpMethod.XGET;
        createSigningKey(AWS_SECRET_KEY_ID ) ;
        service = 'sts';
        resource = '/';

    //  Create all of the bits and pieces using all utility functions above
        HttpRequest request = new HttpRequest();
        request.setMethod(method.name().removeStart('X'));
        setQueryParam('Version', '2011-06-15'); 
        setQueryParam('Action', 'AssumeRole'); 
        setQUeryParam('RoleArn', 'arn:aws:iam::669117241099:role/TestRole');
        setQueryParam('RoleSessionName', 'Swai');       
        String formatedDate = requestTime.formatGmt('yyyyMMdd') + 'T' + '03' + requestTime.formatGmt('mmss') + 'Z';
        setHeader('X-Amz-Date', formatedDate ); 
        setHeader('host', endpoint.getHost()); 

        finalEndpoint = 'https://sts.amazonaws.com' + resource + '?Version=2011-06-15&Action=AssumeRole&RoleArn=arn:aws:iam::559117241080:role/TestRole&RoleSessionName=Swai';
        request.setEndpoint(finalEndpoint);
        String[] headerKeys = new String[0];
        String authHeader = createAuthorizationHeader(); //This is the method that gets the signature)
        request.setHeader( 'host', 'sts.amazonaws.com');
        request.setHeader( 'X-Amz-Date', formatedDate );
        request.setHeader( 'Authorization', authHeader);
        HttpResponse response = new Http().send(request);
        // Parse XML to get SessionToken 
        XMLStreamReader xmlrdr = response.getXmlStreamReader();
        while (xmlrdr.hasNext()) { 
            if (xmlrdr.getEventType() == XMLTag.START_ELEMENT ) { 
                if (xmlrdr.getLocalName() == 'SessionToken') { 
                    while (xmlrdr.hasNext() && xmlrdr.getEventType() != XMLTag.END_ELEMENT){
                        if (xmlrdr.getEventType() == XMLTag.CHARACTERS) { 
                            forPageSessionToken = xmlrdr.getText();
                            break;
                        } else if (xmlrdr.hasNext()) xmlrdr.next();
                          else break;
                    }   
                } else if (xmlrdr.getLocalName() == 'AccessKeyId') { 
                    while (xmlrdr.hasNext() && xmlrdr.getEventType() != XMLTag.END_ELEMENT){
                        if (xmlrdr.getEventType() == XMLTag.CHARACTERS) { 
                            forPageTempAccessKeyId = xmlrdr.getText();
                            break;
                        } else if (xmlrdr.hasNext()) xmlrdr.next();
                          else break;
                    }   
                } else if (xmlrdr.getLocalName() == 'SecretAccessKey') { 
                    while (xmlrdr.hasNext() && xmlrdr.getEventType() != XMLTag.END_ELEMENT){
                        if (xmlrdr.getEventType() == XMLTag.CHARACTERS) { 
                            forPageTempSecretAccessKey  = xmlrdr.getText();
                            break;
                        } else if (xmlrdr.hasNext()) xmlrdr.next();
                          else break;
                    }   
                }
                else if (xmlrdr.hasNext()) xmlrdr.next();
                else break;                     
            } else if (xmlrdr.hasNext()) xmlrdr.next();
            else break;
        }
    }

Thanks a lot Michael for being so helpful and for your prompt responses. I am posting the solution that I have here so that it can benefit others, and hopefully not be stuck for this long.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM