Skip to content

Commit 2b40dce

Browse files
committed
AWS SDK for iOS 1.6.0
1 parent 0d1bd31 commit 2b40dce

File tree

215 files changed

+10301
-1290
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

215 files changed

+10301
-1290
lines changed

NOTICE.txt

+2
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@ Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
33

44
This product includes software developed by
55
Amazon Technologies, Inc (http://www.amazon.com/).
6+
Facebook, Inc (http://www.facebook.com).
67

78
**********************
89
THIRD PARTY COMPONENTS
910
**********************
1011
This software includes third party software subject to the following copyrights:
1112
- SBJson.
1213
- CRC32 calculation function from PHP - Copyright (c) 1997-2012 The PHP Group
14+
- Facebook login and session management from developers.facebook.com - Copyright 2012 Facebook, Inc
1315

1416
The licenses for these third party components are included in LICENSE.txt

samples/AWSPersistence_Locations2/CoreData-Checkin.png

100755100644
File mode changed.

samples/AWSPersistence_Locations2/CoreData-Location.png

100755100644
File mode changed.

samples/AWSPersistence_Locations2/CoreData-Model.png

100755100644
File mode changed.

samples/AWSPersistence_Locations2/CoreData.html

100755100644
File mode changed.

samples/AWSPersistence_Locations2/Locations2.xcodeproj/project.pbxproj

100755100644
File mode changed.
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
<html>
2+
<head>
3+
<title>Web Identity Federation with Mobile Applications</title>
4+
<style type="text/css">
5+
table.sample {
6+
border-width: 2px;
7+
border-spacing: 5px;
8+
border-style: dashed;
9+
border-color: cornflowerblue;
10+
}
11+
table.sample td {
12+
padding: 5px;
13+
}
14+
table.sample tr {
15+
padding: 5px;
16+
}
17+
</style>
18+
</head>
19+
<body style="padding: 10px">
20+
<h1>Introducing Web Identity Federation</h1>
21+
<p>
22+
<a href="http://docs.amazonwebservices.com/STS/latest/APIReference/Welcome.html?r=7687">AWS Security Token Service (STS)</a> now offers <a href="http://docs.amazonwebservices.com/STS/latest/UsingSTS/CreatingWIF.html">Web Identity Federation</a> (WIF). This allows a developer to federate their application from Facebook, Google, or Amazon with their AWS account, allowing their end users to authenticate with one of these Identity Providers (IdP) and receive temporary AWS credentials. In combination with <a href="http://docs.aws.amazon.com/IAM/latest/UserGuide/PolicyVariables.htm">Policy Variables</a>, WIF allows the developer to restrict end users' access to a subset of AWS resources within their account. This article shows how WIF can be used to give many users a "Personal File Store" all housed within a single Amazon S3 bucket <b>without the need for any backend infrastructure</b>. It is adapted from a <a href="http://aws.amazon.com/code/4598681430241367">previous article</a> which used a custom Token Vending Machine hosted in AWS Elastic Beanstalk.
23+
</p>
24+
<h3>Policies</h3>
25+
<p>
26+
Policies are used to specify permissions for temporary credentials, an IAM user, or IAM role. For Web Identity Federation, there are actually two policies, one which specifies who can assume the role (the trusted entity, or principal), and one policy to specify the actual AWS actions and resources that the user will have access to (the access policy). When creating your WIF Role via the <a href="https://console.aws.amazon.com/iam/home">AWS Management Console</a>, the Role Creation Wizard will walk you through the process of creating the trusted entity policy, but you will need to supply the access policy by hand. Below is the policy that should be used with the sample for Facebook login.
27+
<p>
28+
29+
<pre>
30+
{
31+
"Version":"2012-10-17",
32+
"Statement":[{
33+
"Effect":"Allow",
34+
"Action":["s3:GetObject", "s3:PutObject", "s3:DeleteObject"],
35+
"Resource": "arn:aws:s3:::__MY_APPS_BUCKET_NAME__/${graph.facebook.com:id}/*"
36+
},
37+
{
38+
"Effect":"Allow",
39+
"Action":"s3:ListBucket",
40+
"Resource":["arn:aws:s3:::__MY_APPS_BUCKET_NAME__"],
41+
"Condition":
42+
{"StringLike":
43+
{"s3:prefix":"${graph.facebook.com:id}/"}
44+
}
45+
}
46+
]
47+
}
48+
</pre>
49+
50+
51+
<p>
52+
The developer should replace the string __MY_APPS_BUCKET_NAME__ with the appropriate value. In the above policy, each statement has a specific effect:
53+
<ul>
54+
<li>The first statement allows each application user to get, put and delete objects in the specified Amazon S3 bucket, but requires that the object name be prefixed with their Facebook user id. This has the effect of "partitioning" the users into separate "folders" of the Amazon S3 bucket.</li>
55+
<li>The second statement allows users to list only their object's contents by enforcing the prefix condition on the specified bucket.</li>
56+
</ul>
57+
</p>
58+
59+
<h1>The Amazon S3 Personal File Store Sample Application</h1>
60+
61+
<h2>Connecting with the Identity Provider</h2>
62+
63+
<p>Web Identity Federation and this sample application support three Identity Providers, <a href="http://www.facebook.com">Facebook</a>, <a href="http://plus.google.com">Google</a>, and <a href="http://amazon.com/">Amazon</a>. By default, only Facebook login is enabled in the sample and this article will discuss how it is integrated. Please refer to the README HTML files included with the sample to see how to enable login with Google and Amazon. This sample includes version 3.2.1 of the <a href="https://developers.facebook.com/ios/">Facebook SDK for iOS</a> and version 3.0.1 of the <a href="https://developers.facebook.com/android/">Facebook SDK for Android</a>. Using newer versions of the Facebook SDK may require modifications of the sample for compatability.</p>
64+
65+
<p>After successfully authenticating with Facebook, your application will be able to access a Facebook <code>Session</code> (<code>FBSession</code> on iOS). This session will include an <code>access_token</code> which it will need to send to AWS STS along with some additional information.
66+
<ul><li>iOS</li></ul>
67+
<p style="padding-left:2cm;">
68+
<table class="sample"><tr><td align="left" >
69+
<pre>
70+
SecurityTokenServiceAssumeRoleWithWebIdentityRequest *request = [[[SecurityTokenServiceAssumeRoleWithWebIdentityRequest alloc] init] autorelease];
71+
request.webIdentityToken = session.accesToken;
72+
request.providerId = @"graph.facebook.com";
73+
request.roleArn = ROLE_ARN;
74+
request.roleSessionName = @"wifSession";
75+
76+
SecurityTokenServiceAssumeRoleWithWebIdentityResponse *response = [sts assumeRoleWithWebIdentity:request];
77+
78+
NSString *subjectFromWIF = response.subjectFromWebIdentityToken;
79+
AmazonCredentials *credentials = [[[AmazonCredentials alloc] initWithAccessKey:response.credentials.accessKeyId
80+
withSecretKey:response.credentials.secretAccessKey
81+
withSecurityToken:response.credentials.sessionToken] autorelease];
82+
83+
s3 = [[AmazonS3Client alloc] autorelease];
84+
[s3 initWithCredentials:credentials];
85+
</pre>
86+
</table>
87+
</p>
88+
<ul><li>Android</li></ul>
89+
<p style="padding-left:2cm;">
90+
<table class="sample"><tr><td align="left" >
91+
<pre>
92+
AssumeRoleWithWebIdentityRequest request = new AssumeRoleWithWebIdentityRequest()
93+
.withWebIdentityToken(session.getAccessToken())
94+
.withProviderId("graph.facebook.com")
95+
.withRoleArn(ROLE_ARN)
96+
.withRoleSessionName("wifSession");
97+
98+
AssumeRoleWithWebIdentityResult result = sts.assumeRoleWithWebIdentity(request);
99+
100+
Credentials stsCredentials = result.getCredentials();
101+
String subjectFromWIF = result.getSubjectFromWebIdentityToken();
102+
BasicSessionCredentials credentials = new BasicSessionCredentials(stsCredentials.getAccessKeyId(),
103+
stsCredentials.getSecretAccessKey(),
104+
stsCredentials.getSessionToken());
105+
106+
s3Client = new AmazonS3Client(credentials);
107+
</pre>
108+
</table>
109+
</p>
110+
111+
<p>The required additional information which we need to supply to the request is:
112+
<ul>
113+
<li><code>ProviderId</code> - the name of the IdP. The supported values are <b>graph.facebook.com</b>, <b>www.amazon.com</b>, and <b>googleapis.com</b>.</li>
114+
<li><code>RoleArn</code> - the Amazon Resource Name of the Role the user will assume. Will be of the format <b>arn:aws:iam::123456789:role/myWebIdentityRole</b>.</li>
115+
<li><code>RoleSessionName</code> - the name to give to this session. Will be used to identify the session.</li>
116+
</ul>
117+
118+
It is also possible to control the duration of the session token generated, though the same restrictions exist for WIF calls as other AWS STS calls. Refer to the <a href="http://docs.aws.amazon.com/STS/latest/APIReference/">AWS STS API</a> guide for more details.</p>
119+
120+
<p>If we call AWS STS as above, we still need to extract the credentials and the user identifier from the identity provider from the response object and pass them to our individual service clients. Our application would also need to call <code>AssumeRoleWithWebIndentity</code> each time our AWS credentials expire. To help with managing WIF credentials, both the iOS and Android SDKs offer a credentials provider which wraps the calls to <code>AssumeRoleWithWebIdentity</code>.
121+
122+
<ul><li>iOS</li></ul>
123+
<p style="padding-left:2cm;">
124+
<table class="sample"><tr><td align="left" >
125+
<pre>
126+
AmazonWIFCredentialsProvider *wif = [[AmazonWIFCredentialsProvider alloc] initWithRole:FB_ROLE_ARN
127+
andWebIdentityToken:self.session.accessTokenData.accessToken
128+
fromProvider:@"graph.facebook.com"];
129+
130+
NSString *subjectFromWIF = wif.subjectFromWIF;
131+
s3 = [[[AmazonS3Client alloc] autorelease] initWithCredentialsProvider:wif];
132+
</pre>
133+
</table>
134+
</p>
135+
<ul><li>Android</li></ul>
136+
<p style="padding-left:2cm;">
137+
<table class="sample"><tr><td align="left" >
138+
<pre>
139+
WebIdentityFederationSessionCredentialsProvider wif =
140+
new WebIdentityFederationSessionCredentialsProvider(fbSession.getAccessToken(),
141+
"graph.facebook.com",
142+
ROLE_ARN);
143+
String subjectFromWIF = wif.getSubjectFromWIF();
144+
s3 = new AmazonS3Client(wif);
145+
</pre>
146+
</table>
147+
</p>
148+
On iOS, the credentials provider will handle refreshing the AWS credentials for you, on Android <code>refresh()</code> may need to be called manually. Unfortunately, the Identity Provider's token (access_token for Facebook) also has an expiration. On both iOS and Android, the provider will not manage the expiration of the Identity Provider's credentials. Please refer to the individual prodiver's documentation for how to manage expiration of credentials.</p>
149+
150+
<h2>Accessing Partitioned S3</h2>
151+
152+
<p>
153+
The policy we applied to our WIF role requires the AWS Mobile SDKs to be used in a specific fashion in order to list, get, and put objects within the user's partition of Amazon S3. In the following section, we show the relevant code snippets from the sample application.</p>
154+
155+
<h3>Put Object</h3>
156+
<p>Putting objects into the application bucket requires that the user's username be a prefix followed by the forward slash ("/") character.</p>
157+
<ul><li>iOS</li></ul>
158+
<p style="padding-left:2cm;">
159+
<table class="sample"><tr><td align="left" >
160+
<pre>
161+
NSString *keyName = [NSString stringWithFormat:@"%@/%@", subjectFromWIF, objectName.text];
162+
163+
S3PutObjectRequest *por = [[[S3PutObjectRequest alloc] initWithKey:keyName inBucket:__MY_APPS_BUCKET_NAME__] autorelease];
164+
por.data = data;
165+
166+
[s3Client putObject:por];
167+
</pre>
168+
</table>
169+
</p>
170+
<ul><li>Android</li></ul>
171+
<p style="padding-left:2cm;">
172+
<table class="sample"><tr><td align="left" >
173+
<pre>
174+
ByteArrayInputStream bais = new ByteArrayInputStream( data.getBytes() );
175+
ObjectMetadata metadata = new ObjectMetadata();
176+
metadata.setContentLength( data.getBytes().length );
177+
178+
String keyName = subjectFromWIF + "/" + objectName.getText().toString();
179+
s3Client.putObject(__MY_APPS_BUCKET_NAME__, keyName, bais, metadata );
180+
</pre>
181+
</table>
182+
</p>
183+
184+
<h3>Listing Objects</h3>
185+
<p>The only requirement to list objects in the application's bucket is to provide the prefix. The prefix is the user's username followed by a forward slash ("/"), as required by the policy.</p>
186+
<ul><li>iOS</li></ul>
187+
<p style="padding-left:2cm;">
188+
<table class="sample"><tr><td align="left" >
189+
<pre>
190+
S3ListObjectsRequest *listObjectsRequest = [[[S3ListObjectsRequest alloc] initWithName:__MY_APPS_BUCKET_NAME__] autorelease];
191+
listObjectRequest.prefix = [NSString stringWithFormat:@"%@/", subjectFromWIF];
192+
193+
S3ListObjectsResponse *listObjectResponse = [s3Client listObjects:listObjectRequest];
194+
</pre>
195+
</table>
196+
</p>
197+
<ul><li>Android</li></ul>
198+
<p style="padding-left:2cm;">
199+
<table class="sample"><tr><td align="left" >
200+
<pre>
201+
ListObjectsRequest req = new ListObjectsRequest();
202+
req.setBucketName( __MY_APPS_BUCKET_NAME__ );
203+
req.setPrefix( subjectFromWIF + "/" );
204+
205+
ObjectListing objects = s3Client.listObjects( req );
206+
</pre>
207+
</table>
208+
</p>
209+
210+
<h3>Get Object</h3>
211+
<p>
212+
When listing the objects, the names returned contain the user-specific prefix as part of the name. Therefore, getting objects does not require additional logic.
213+
<ul><li>iOS</li></ul>
214+
<p style="padding-left:2cm;">
215+
<table class="sample"><tr><td align="left" >
216+
<pre>
217+
S3GetObjectRequest *getObjectRequest = [[[S3GetObjectRequest alloc] initWithKey:__OBJECT_NAME__
218+
withBucket:__MY_APPS_BUCKET_NAME__] autorelease];
219+
S3GetObjectResponse *getObjectResponse = [s3Client getObject:getObjectRequest];
220+
</pre>
221+
</table>
222+
</p>
223+
<ul><li>Android</li></ul>
224+
<p style="padding-left:2cm;">
225+
<table class="sample"><tr><td align="left" >
226+
<pre>
227+
S3Object objectData = s3Client.getObject( __MY_APPS_BUCKET_NAME__, __OBJECT_NAME__ );
228+
</pre>
229+
</table>
230+
</p>
231+
232+
</p>
233+
</p>
234+
235+
<h2>References</h2>
236+
<p>The full sample code is included in the AWS Mobile SDKs. Follow these links to download the AWS Mobile SDKs:</p>
237+
238+
<ul>
239+
<li><a href="http://aws.amazon.com/sdkforios">AWS SDK for iOS</a></li>
240+
<li><a href="http://aws.amazon.com/sdkforandroid">AWS SDK for Android</a></li>
241+
</ul>
242+
243+
<p>For more information about policies, read the following topics:</p>
244+
<ul>
245+
<li><a href="http://docs.amazonwebservices.com/IAM/latest/UserGuide/PoliciesOverview.html?r=3093">Overview of Policies</a></li>
246+
<li><a href="http://docs.amazonwebservices.com/IAM/latest/UserGuide/ExampleIAMPolicies.html">Example Policies</a></li>
247+
<li><a href="http://docs.amazonwebservices.com/IAM/latest/UserGuide/AccessPolicyLanguage_HowToWritePolicies.html">How to Write a Policy</a></li>
248+
<li><a href="http://docs.amazonwebservices.com/IAM/latest/UserGuide/Using_SpecificProducts.html">Table of Links to Service Specific Policy Documentation</a></li>
249+
<li><a href="http://awspolicygen.s3.amazonaws.com/policygen.html">Policy Generator</a></li>
250+
</ul>
251+
252+
<p>For more information about the AWS Security Token Service, follow this link<p>
253+
<ul>
254+
<li><a href="http://docs.amazonwebservices.com/STS/latest/APIReference/Welcome.html?r=829">AWS Security Token Service</a></li>
255+
</ul>
256+
257+
<h2>Questions?</h2>
258+
<p>Please feel free to ask questions or post comments in the <a href="https://forums.aws.amazon.com/forum.jspa?forumID=88">Mobile Development Forum</a>.</p>
259+
260+
</body>
261+
</html>

0 commit comments

Comments
 (0)