| Did this page help you? Yes No Tell us about it... |
Your product will make calls to the Amazon Simple Storage Service on behalf of a customer. These calls are part of the overall process products follow to work with Amazon DevPay (for more information, see How a Product Works with DevPay).
This section describes how the product makes requests to Amazon S3 and uses the customer's
credentials. For the Java, C#, and Ruby sample code, you can search for the differences between the
original Amazon S3 library and the new DevPay version of the library to easily see what we've changed.
The changes are in the AWSAuthConnection class. For information about where to get the
original Amazon S3 library, see About the Sample Code.
For desktop products, the credentials your product must retrieve are the customer's Access Key
ID, Secret Access Key, and user token. For web products, the only credential is the customer's
user token. Your product must retrieve and decode the credentials from their secure store
location. How you store and retrieve them is up to you. For an example of one way to handle them,
see the FileCredentialStore class in the security directory in the
sample code package.
Desktop products and web products must include the customer's user token in the Amazon S3
request. In addition, desktop products must include the product token (it's optional for web
products that have a user token created after May 15, 2008). To include the
tokens in the request, you add an x-amz-security-token header for each token. The
following example shows a basic REST request (with the additional headers in red).
Date: Wed, 27 Jun 2007 03:40:41 GMT Authorization: AWS 0PN6J17HBGXHT7JJ3X83:frJIUN8DYpKDtOLCwo//yllqDzgEXAMPLE=x-amz-security-token: {UserToken}AAAHVXNlclRrbgfOpSykBAXO7g/zG....[long encoded token]...x-amz-security-token: {ProductToken}MIIBzTCCATagAwIBAgIGARB1qe....[long encoded token]...
An alternate method for passing both tokens is to add a single x-amz-security-token
header with the tokens separated by a comma.
The following shows how to add the tokens to the request.
For Java, make sure you add the two x-amz-security-token
headers and not put them. Because the headers have the same name, if you
put them, you'll overwrite the first with the second.
The following code snippet uses a single x-amz-security-token header with the
values separated by a comma.
HttpURLConnection connection = ...;
connection.addRequestProperty("x-amz-security-token", userToken + "," + productToken);HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.Headers.Add("x-amz-security-token", userToken + "," + productToken);The following code snippet shows the method in the C++ sample code that performs the initial
step to get the headers added to the request (this code creates a map; see
CppDevPaySample\s3\AWSAuthConnection.cpp). The line in red near the end of
the snippet adds the user token and product token.
void AWSAuthConnection::addHeaders(REQUEST_TYPE method, int length, strmap &headers)
{
string temp;
//Add standard headers to the existing ones
headers.insert(pair<string, string> (string("Host"), server_));
temp.erase(); temp = utils_.getHTTPDate();
headers.insert(pair<string, string> (string("Date"), temp));
switch(method)
{
case PUT:
if(length > 0)
{
headers.insert(pair<string, string> (string("Content-Type"),string("binary")));
}
else
{
headers.insert(pair<string, string> (string("Content-Type"), string("")));
}
headers.insert(pair<string, string> (string("Content-length"), utils_.itos(length)));
headers.insert(pair<string, string> (string("Content-md5"), string("")));
break;
case GET:
case DELETE:
headers.insert(pair<string, string> (string("Content-Type"), string("")));
headers.insert(pair<string, string> (string("Content-md5"), string("")));
break;
}
if(!securityTokens_.empty())
{
set<string>::iterator i;
for(i = securityTokens_.begin(); i != securityTokens_.end(); i++)
{
headers.insert(pair<string, string> (utils_.AMAZON_SECURITY_HEADER, (*i)));
}
}
return;The following code snippet uses a single x-amz-security-token header with the
values separated by a comma.
http = Net::HTTP.new(server, port) request = Net::HTTP::Get.new(path) ... request['x-amz-security-token'] = product_token + "," + user_token ... http.request(request)
How you sign the Amazon S3 request for a DevPay product is essentially no different from how you
do it for a product that doesn't use DevPay. You still sign the request with a Secret Access Key
and include an Access Key ID in the Authorization header. For desktop products, you
use the customer's Secret Access Key and Access Key ID. For web products, you use your Secret
Access Key and Access Key ID.
When creating the string to sign, you still include any headers that start with
x-amz, as discussed in the Amazon S3 documentation. The two new headers you added
in the previous section start with x-amz, so they are included when the string to
sign is created by your code. For information about how to sign an Amazon S3 request, go to the
Amazon Simple Storage Service
Developer Guide. Also refer to the basic Amazon S3 libraries (for information about
their location, see About the Sample Code).
The existing Java Amazon S3 library that we started with did not have to be modified because
all the headers that begin with x-amz were already included in the string.
The existing C# Amazon S3 library that we started with did not have to be modified because
all the headers that begin with x-amz were already included in the string.
The C++ sample code handles the x-amz-security-token headers separately from
the other headers that begin with x-amz. The following snippet is from
CppDevPaySample\s3\Utils.cpp.
1AMAZON_SECURITY_HEADER = "x-amz-security-token";
2...
3if(temp.compare(0, AMAZON_SECURITY_HEADER.size(), AMAZON_SECURITY_HEADER) == 0)
4{
5 if(isSecurityHeaderAdded == false)
6 {
7 bool isFirst = true;
8 ret = sortedheaders.equal_range(AMAZON_SECURITY_HEADER);
9 result.append(AMAZON_SECURITY_HEADER);
10 for(j = ret.first; j != ret.second; j++)
11 {
12 result.append((isFirst == true) ? ":" : ",");
13 trimmedval.erase();
14 trimmedval = trimString((*j).second);
15 result.append(trimmedval);
16 if(isFirst == true)
17 isFirst = false;
18 }
19 result.append("\n");
20 isSecurityHeaderAdded = true;w
21 }
22}
23 LASTLINEThe existing Ruby Amazon S3 library that we started with did not have to be modified because
all the headers that begin with x-amz were already included in the string.