从服务器向AWS JS SDK发送签名,而不是使用纯文本密钥

时间:2016-03-30 03:01:05

标签: javascript amazon-s3 salesforce aws-sdk

是否有办法将签名版本的密钥发送到AWS JS SDK,而不是以纯文本形式发送密钥adn访问密钥。我正在使用Salesforce并希望在Salesforce中创建签名并将其发送到Javascript(或VF页面)签名,然后可以在AWS SDK标注中使用该签名,而不是客户端的密钥。

2 个答案:

答案 0 :(得分:1)

您可以看到将凭据嵌入客户端的明显问题。

亚马逊Security Token Service (STS)是此问题的一种解决方案。

您的应用程序后端系统向STS发送临时凭证请求。这些凭证允许拥有它们的实体仅执行由令牌授权的动作,这是添加到通常(访问密钥id,访问密钥秘密)元组的第三属性,并且权限仅在令牌到期之前有效。请注意,令牌不使用您的访问密钥和密钥,它实际上带有自己的访问密钥和密钥,所有这些都是短命的并且是“一次性的”。

从某种意义上说,您使用的短语“发送签名版本的密钥”可以很好地描述这一点。从某种意义上说,这是一次性授权。

另见http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html

答案 1 :(得分:0)

我终于可以使用Apex Code从Salesforce打电话给STS,这一切都归功于迈克尔。然后返回会话令牌,临时访问密钥和临时密钥。以下是我用来调用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;
        }
    }

非常感谢迈克尔的帮助和你的迅速回应。我发布了我在这里的解决方案,以便它可以使其他人受益,并且希望不会被困在这么长时间。