AssumeRole - AWS iOS SDK sample - ios

I am using "AssumeRole" api in iOS AWS sdk to generate temporary security credentials. Can anybody tell the steps for this or give sample app for this?
TSC = [[AmazonSecurityTokenServiceClient alloc]initWithAccessKey:#"XXXXXXXXXXXXXXXX" withSecretKey:#"uuuuuuuuuuuyyyyyyyy" ];
request = [[SecurityTokenServiceAssumeRoleRequest alloc]init ];
request.roleArn = #"arn:aws:iam::0000000000:role/test";
request.roleSessionName = #"test";
request.policy =nil;
request.durationSeconds=[NSNumber numberWithInt:3600];
request.externalId=#"test123";
response = [TSC assumeRole:request];
My doubt is to get temporary credentials, the above code will be enough or do i need call the NSURLConnection delegates explicitly to make the web service call? Thanks.

That code should be enough to get credentials. If the request is successful, the credentials will be available in the response object. (API reference).
You'll need to initialize a AmazonCredentials object to use the returned credentials:
AmazonCredentials *credentials =
[[AmazonCredentials alloc] initWithAccessKey:response.credentials.accessKeyId
withSecretKey:response.credentials.secretAccessKey
withSecurityToken:response.credentials.sessionToken];
AmazonS3Client *s3 = [[AmazonS3Client alloc] initWithCredentials:credentials];

Related

Why is AWS EC2 not working on iOS and MacOS?

So basically I'm writing a tool for managing some EC2 instances, nothing special.
I managed to get some AWS framework to build for MacOS (incredible that it is not officially supported) and I'm now trying to use the describeInstances() request of the framework.
I always get the same error : Domain=com.amazonaws.AWSEC2ErrorDomain Code=0
I've tried the same code on iOS, same issue.
I've tried on a python script, using the Boto3 library, and no problem here, the function returns my instances and the descriptions.
I already use AWSS3 and AWSSNS on the same MacOS project, with no issue.
I have my policies set on IAM, for EC2 set on "fullAccess"
Here's the code:
AWSCognitoCredentialsProvider *credentialsProvider = [[AWSCognitoCredentialsProvider alloc]
initWithRegionType:AWSRegionUSEast1
identityPoolId:kPoolID];
AWSServiceConfiguration *configuration = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSEast1 credentialsProvider:credentialsProvider];
[AWSServiceManager defaultServiceManager].defaultServiceConfiguration = configuration;
AWSEC2 *ec2 = [AWSEC2 defaultEC2];
AWSEC2DescribeInstancesRequest *request = [AWSEC2DescribeInstancesRequest new];
[ec2 describeInstances:request completionHandler:^(AWSEC2DescribeInstancesResult * _Nullable response, NSError * _Nullable error) {
if(error){
NSLog(#"%# = %#", #"EC2 describe Error", error);
}else{
NSLog(#"%# = %#", #"EC2 describe Response", response);
}
}];
Can anyone help me with this?
For some reason EC2 does not want to take the cognito pool is as a form of authentication, I had to connect using access and secret key to make it work.

Creating a private Amazon API Gateway

I want to create an api for my app that is only accessible by my app. I have added the AWS Cognito identity to my appDelegate like so:
AWSCognitoCredentialsProvider *credentialsProvider = [[DeveloperAuthenticationProvider alloc] initWithRegionType:AWSRegionUSEast1 identityPoolId:#"poolId"];
AWSServiceConfiguration *configuration = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSEast1 credentialsProvider:credentialsProvider];
AWSServiceManager.defaultServiceManager.defaultServiceConfiguration = configuration;
__block NSString *cognitoId = nil;
// Retrieve your Amazon Cognito ID
[[credentialsProvider getIdentityId] continueWithBlock:^id(AWSTask *task)
{
if (task.error)
{
NSLog(#"Error: %#", task.error);
}
else
{
// the task result will contain the identity id
cognitoId = task.result;
}
return nil;
}];
How do I use this gonitoId that gets returned to make sure that this is the only app with the id that can access my api? Do I need to save this id and use it when accessing the api?
Thanks.
Securing the API with 'AWS_IAM' authorization will require that requests are signed with credentials in the same AWS account. Past that, if you are in control of the account then you should be able to ensure that only the Cognito roles have access by setting a fine-grained policy with the API Gateway actions and resources.
http://docs.aws.amazon.com/apigateway/latest/developerguide/permissions.html#api-gateway-calling-api-permissions
The app should be receiving Cognito credentials when authenticated so you'll use in the API Gateway SDK. The generated SDKs are available in iOS Android and JavaScript.
http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-generate-sdk.html

How to fix this error in sending emails by Outh2 using MailCore?

Im using mailcore to for sending mails using access token. This work fine in case of using password but by using access tokens its not working. I have changed every combination of ports and connection types but still getting the same issue. I need some help.
MCOSMTPSession * smtpSession = [[MCOSMTPSession alloc] init];
smtpSession.hostname = #"smtp.gmail.com";
smtpSession.port = 465;
smtpSession.username = user; //saved value
smtpSession.connectionType = MCOConnectionTypeTLS;
smtpSession.OAuth2Token = token; //saved value(Validated)
smtpSession.authType = MCOAuthTypeXOAuth2;
smtpSession.checkCertificateEnabled=NO;
MCOMessageBuilder * builder = [[MCOMessageBuilder alloc] init];
MCOAddress *fromAdress=[[MCOAddress alloc]init];
fromAdress = [MCOAddress addressWithMailbox:user];
MCOAddress *toAdress=[[MCOAddress alloc]init];
toAdress = [MCOAddress addressWithMailbox:self.to.text];
[[builder header] setFrom:fromAdress];
[[builder header] setTo:#[toAdress]];
NSString *htmlbody1=#"Body";
[[builder header] setSubject:#"Some_subject"];
[builder setHTMLBody:htmlbody1];
[smtpSession setConnectionLogger:^(void * connectionID, MCOConnectionLogType type, NSData * data) {
NSString *response = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"Response %#",response);
}];
NSData * rfc822Data = [builder data];
MCOSMTPSendOperation *sendOperation = [smtpSession sendOperationWithData:rfc822Data];
[sendOperation start:^(NSError *error) {
if(error) {
NSLog(#"Error sending email: %#", error);
} else {
}
}];
im getting this response
Response 535-5.7.8 Username and Password not accepted. Learn more at
535 5.7.8 https://support.google.com/mail/answer/14257 gg7sm1578291wjd.10
and getting this error
Error Domain=MCOErrorDomain Code=5 "Unable to authenticate with the current session's credentials.
It's worth noting that if you want to send emails via Gmail, then you need to either:
Use Oauth (more details, see below)
For users with 2-step verification enabled, have them set up an App password that they then enter in the app
Have users enable the Less Secure Apps option on their account
Using OAuth
For OAuth, you can use a library like GTMAppAuth, which allows you to create an OAuth token to use within your app. However, when doing so, you must make sure to set the scope correctly when requesting access. Here's some code taken from the wiki:
OIDAuthorizationRequest *request =
[[OIDAuthorizationRequest alloc] initWithConfiguration:configuration
clientId:kClientID
clientSecret:kClientSecret
scopes:#[OIDScopeOpenID, OIDScopeProfile]
redirectURL:redirectURI
responseType:OIDResponseTypeCode
additionalParameters:nil];
Sending via SMTP
If you want to use SMTP to send email, then you must add #"https://mail.google.com/" to the scopes` argument.
Note that it seems that in 2022, Google really doesn't want you directly accessing SMTP. If you use the scope #"https://mail.google.com/" in your app, then your app is considered Restricted and it'll need to go through a verification process.
Sending via Google APIs
The alternative is to send via the Google APIs. If you want to do this, then you need the #"https://www.googleapis.com/auth/gmail.send" scope. This will allow you to send email e.g. using the GTLR library.
Notes:
If you try to use the #"https://www.googleapis.com/auth/gmail.send" scope then login via SMTP, you'll get the error Username and Password not accepted. You can't use that scope for SMTP, only for the googleapis.
P.S. Why Google can't better document this, is beyond me. I've just volunteered 20 hours of my time to Google for figuring this out.

Office 365 iOS: Not able to fetch List Items from Office 365 SDK

I have added the announcement app and added few items to it, now i want to fetch the items from my announcement list so I have used the below code
token_Obtained_During_first_time_Login: This is the token that i get when i login for the first time using the acquireTokenWithResource method of ADAuthenticationContext class
- (void)getClientList {
NSString *appToken = [[NSUserDefaults standardUserDefaults]
valueForKey:#"token_Obtained_During_first_time_Login"];
NSString* hostName = #"https://myTenant.sharepoint.com/sites/myApp";
OAuthentication *credentials = [[OAuthentication alloc] initWith:appToken];
ListClient *client = [[ListClient alloc]
initWithUrl:hostName
credentials:credentials];
NSURLSessionTask* task = [client getListItems:#"MyAnnouncements"
callback:^(NSMutableArray *listItems, NSError *error) {
if (error==nil) {
NSLog(#"%#",listItems);
}
}];
[task resume];
}
I have even debugged the 365 code and it provides me the below URL for getListItems: callback method
https://myTenant.sharepoint.com/sites/myApp/_api/lists/GetByTitle('MyAnnouncements')/Items
I have even tried the same using getTokenWith method which comes with the sample code
- (void)getAnnouncementList:(void (^)(ListClient *))callback{
NSString* hostName = #"https://myTenant.sharepoint.com";
[self getTokenWith:hostName :true completionHandler:^(NSString *token) {
OAuthentication *credentials = [[OAuthentication alloc] initWith:token];
callback([[ListClient alloc]initWithUrl:hostName credentials:credentials]);
}];
}
But still no luck i get the list as nil
Please guide on how this can be resolved, I have even verified the rights in the Azure Directory everything seems fine am able to fetch data of one drive, mails and calendar but list is a place where i am stuck.
Every time i call the above code i get the response nil not sure what am passing wrong, my guess is the token.
I resolved this issue by making a change in the apiUrl present in the ListClient.m file of Office 365.
All i did was changed it to
const NSString *apiUrl = #"/sites/mobileApp/_api/web/Lists";
Making the above change did the trick and now i can access all the list data.

vimeo oAth authentication through iPhone app

I have an iPad app and need to integrate vimeo to it. I'm in the initial stages of integrating it to my app. I first need to authenticate my app through vimeo.
I've gone through the steps for authentication in documentation and I'm able to pass through first 2 steps:
Request Token:
http://vimeo.com/oauth/request_token
User Authorization:
http://vimeo.com/oauth/authorize
But unable to get oauth_token and oauth_token_secret through last step:
Access Token:
http://vimeo.com/oauth/access_token
Vimeo redirects to callback url instead of going back to the app which is fine until I get verifier and authorization token. But once I use these to get oauth_token and oauth_token_secret, console shows following error message:
Error Domain=NSURLErrorDomain Code=-1012 "The operation couldn’t be completed.
(NSURLErrorDomain error -1012.)" UserInfo=0x18146180 {
NSErrorFailingURLKey=http://vimeo.com/oauth/access_token?oauth_token=141b4ff56c48dc5d03501297bde85ebc&oauth_verifier=land-1886924229,
NSErrorFailingURLStringKey=http://vimeo.com/oauth/access_token?oauth_token=141b4ff56c48dc5d03501297bde85ebc&oauth_verifier=land-1886924229,
NSUnderlyingError=0x181483d0 "The operation couldn’t be completed. (kCFErrorDomainCFNetwork error -1012.)"
}
Can anyone please help or atleast provide some directions?
To further give an insight, I'm using OAuthConsumer framework. Below are the lines of code where we place request to get an access token:
- (void)successfulAuthorizationWithToken:(NSString *)token verifier:(NSString *)verifier {
NSLog(#"successfulAuthorizationWithToken");
OAMutableURLRequest *request;
OADataFetcher *fetcher;
//NSURL *url = [NSURL URLWithString:#"https://api.twitter.com/oauth/access_token"];
NSURL *url = [NSURL URLWithString:#"http://vimeo.com/oauth/access_token"];
request = [[[OAMutableURLRequest alloc] initWithURL:url
consumer:self.consumer
token:self.accessToken
realm:nil
signatureProvider:nil autorelease];
OARequestParameter *p0 = [[OARequestParameter alloc] initWithName:#"oauth_token"
value:token];
OARequestParameter *p1 = [[OARequestParameter alloc] initWithName:#"oauth_verifier"
value:verifier];
NSArray *params = [NSArray arrayWithObjects:p0, p1, nil];
[request setParameters:params];
fetcher = [[[OADataFetcher alloc] init] autorelease];
[fetcher fetchDataWithRequest:request
delegate:self
didFinishSelector:#selector(accessTokenTicket:didFinishWithData:)
didFailSelector:#selector(accessTokenTicket:didFailWithError:)];
[p0 release];
[p1 release];
}
I've also tried solutions specified in below link:
Twitter API + OAuthConsumer.framework
It says to use [[[OAHMAC_SHA1SignatureProvider alloc] init] autorelease] as signatureProvider. But the results are same.
I need to get following values after I get verifier and authorized token using the access token step:
oauth_token=YourAuthorizedOauthToken&oauth_token_secret=YourAuthorizedTokenSecret
You need to provide your own callback in your request, which looks like myapp://... and register myapp handler in iOS, so that when browser is redirected then iOS will give control back to your app. I'm assuming you are using OAuth properly and start a browser from your app for user interaction. Alternatively you could use a WebView (not what OAuth recommends) then in the WebView delegate you can catch a redirect and parse access toke out.
Finally got it working. There were issues in the base string and oAuth Header string format.

Resources