AWS Cognito: immediately signed-put after sign-in - ios

Context
I use booth Cognito User Pools and Cognito Identity Pools to sign-in user.
I want to achieve the simple task to sign-in a user on a iOS app, a Swift app.
My app is based on custom version of Mobile Hub Help to allow the use of Cognito User Pools. See A Swift Sample Sign-In App (using aws-mobile hub-helper) with Cognito User Pools
There is two steps in app: first one is only launch and second one is Sign-In after user touch a Sign-In button: user credentials are then hardcoded for sake of minimality.
During the first step, user have to received an unauthorized identityId. Then after second step, user received an auth identityId.
Behavior
Before press signin, step 1, there is 2 requests to AWS:
AWSCognitoIdentityService.GetId
AWSCognitoIdentityService.GetCredentialsForIdentity
After press signing there are 3 more requests:
AWSCognitoIdentityProviderService.InitiateAuth
AWSCognitoIdentityProviderService.RespondToAuthChallenge
AWSCognitoIdentityService.GetId
Before request 5 — AWSCognitoIdentityService.GetId — user is signed-in, as indicated by observer on AWSIdentityManagerDidSignInNotification.
After request 5, an IdentityId is retrieved. But immediately after user is signed-out according to observer on notification AWSIdentityManagerDidSignOutNotification.
What may happen?

It would help to have a look at your logs. But what you need to realize is that cognito sdk REMEMBERS stuff (session id's, identity id's, etc) using keychain and NSUserDefaults. So when you run your hard coded test for a second time, the behavior of your test will probably be different. If you want to start clean, go to the simulator menu and choose reset content and settings (this will clear out the keychain - which stores session stuff, and will clear out the NSUserDefaults which stores sessions that are active).
I just pushed a new version of the repo on the branch AddAllMobileHubDemos. The latest version of the repository has 3 targets defined. SignIn, MySampleApp and Dom. SignIn is a version of my old signin app modified to work with mobile-hub-helper. MySampleApp is a full downloaded MobileHub app with Cognito User Pools built in. There is also Dom, a single page hard coded signin app.
Also check out (in that same repository) the cognito-diagram cognito-diagram.pdf from the latest push, which has some of the possible errors listed. That version has the features I described above.
If you post the logs that might help me be more specific. There are cases where the AWSIdentityManager will log you out (for instance if you try to merge two identities... which you might very well if you are using a hard coded usrname and password and then changed them without ever logging out.)
Bruce

Problem solved!
#Bruce0 led me to answer!
First, on a real device running everything worked as expected.
Second, there were a lot of errors on log:
OSStatus error: [-34018] Security error has occurred.
The answer was to set the "Keychain Sharing" capability to "ON" in "Target->Capabilities" on Xcode.

Related

Twitter App showing code: 89 Invalid or expired token

I have an app that uses the Twitter API where users can authenticate via twitter and retweet/like/follow through my app. Randomly this week the logs are showing "code: 89 Invalid or expired token".
Naturally, I go login to twitter to see the status of my app, and nothing seems out of the ordinary. I saw others with this issue had success regenerating their keys and replacing them in their application.
This didn't help.
One important thing to note is nothing has changed in the code of my application for the last 3-4 months, so I doubt it's anything in there. It's been working for over two years without any issue.
The thing I suspect the most is perhaps Twitter decided to suspend my app; Although, I don't see anywhere that is the case, and I thought I'd receive an email from them about it if it were.
I'm at a loss and would appreciate some possible solutions or alternative avenues I can pursue to find the culprit.
The keys associated with your app are the API Key (Consumer Token) and API secret key (Consumer Secret). The error you're getting is for the Access token, which belongs to the user. It sounds like the user associated with that request needs to authorize your app again before it can operate again with their access key. This can happen if the user removes authorization for your app by visiting their Settings/Privacy and safety/Apps and sessions.
If you were using your own access token in a scenario like single-user authorization, then regenerating the key might work, but in this case, the only way to get new keys for that user is for them to go through the sign-in process to authorize your app again. e.g. you could log who the user was that the error occurred on and send them a notification to re-authorize.

Securing login credentials in an iOS app bundle

I am writing an iOS app and have a dilemma. The app will be used to test the BLE protocol of devices coming off our production line. It needs to be very simple, It is a one button app that automatically connects to devices and tests commands in our protocol and gives a pass or fail result. If it passes the device id is sent to our API to be entered in our database.
My problem is I don't want the user to have to login, but I need to send a username and password to the API to log in. This means the username and password has to be included in the app. I am trying to find out the most secure way to do this. I initially thought I would include a plist in the app with the credentials, enter them in keychain, then delete the plist. However I don't believe you can delete a file included in the app bundle (I get a 513 permission error).
I have 2 questions. Is it secure to include credentials in code? Is there a better way to do this?
Thanks!
No.
Use API to retrieve credentials and store to keychain. Simple call to firebase could solve this. Or use your own backend with your custom “security”.
But even obtaining via API don’t give you 100% security. Everything depends. API solution gives you flexibility and ability to support different versions with different credentials.

iOS - AWS Cognito - "NotAuthorizedException" - Logins don't match

For some reason an account which I've registered using my app and tested before is now giving me an error when trying to log in using its details: "Logins don't match. Please include at least one valid login for this identity or identity pool."
I know the values I am using for it are definitely correct and other accounts are still able to login. What could be the cause of this error?
Any help would be greatly appreciated.
What the SDK is trying to tell you is that the identityId in your Federated Identity Pool (and which may be stored in a keychain in your device, and which may be re-established on restart from an existing session) does not match the login in your authentication provider which was returned by the "logins" method.
This can happen in a number of different ways, but this usually occurs because you attempt to log in as another user on the same authentication provider without first logging out.
The SDK recovers by retrying.
(This recovery does not really work because I think it takes 2 or 3 attempts to time out, and the recovery then leaves you in a state where subsequent logins fail with the same error. Restarting the app clears this. I have not fully investigated the defect in the retry/recovery process)
The solution is to prevent the app from logging in on a different ID with the same authentication provider (IdP) without first logging out of that authentication provider.

Could not fulfill request (error code 7) via openActiveSessionWithReadPermissions with Facebook test users

Background
Recently upgraded to Facebook SDK 3.2
Tested on both device and simulator (iOS 5.1 through 6.1)
Error is only present when attempting to authenticate Facebook test users.
Error
The Facebook server could not fulfill this access request: Temporarily unable to make API calls on behalf of XXXXXX.
UserInfo={com.facebook.sdk:ErrorLoginFailedReason=com.facebook.sdk:SystemLoginCancelled, com.facebook.sdk:ErrorInnerErrorKey=Error Domain=com.apple.accounts Code=7}
Steps to Reproduce
Clear simulator or manually remove Facebook account from device settings.
Create a test user via Facebook's accounts/test-users endpoint.
Add Facebook account in device settings.
Authenticate via openActiveSessionWithReadPermissions & accept the permissions dialog.
Expected Result
FBSessionStateHandler block returns with state == FBSessionStateOpen.
A nil NSError.
Actual Result
FBSessionStateHandler block returns with a error.fberrorCategory == FBErrorCategoryUserCancelled with the above user info trace.
Solution Attempts
I've followed the steps outlined in this question; namely checking my bundle name, ensuring my app type is set to Native/Desktop and setting my App Secret in Client to NO.
As well, I have ensured I am only asking for read permissions (ie. email).
I've even bypassed the Facebook SDK altogether by attempting to authentication with a ACAccountStore instance & got the same results.
Again, everything works fine with a regular user (non-test); so it must have something to do with the configuration & recent 3.2 changes.
1) Facebook 3.1 SDK splits read and publish permissions. Use only read permissions (e.g., email) in the first authentication call. Using both will break it and result in that generic error. It seems Facebook's SDK doesn't actually do what it's meant to do: fall back to older authentication methods. David tells me an updated Parse SDK will make the permissions split easier, but it will of course be up to Facebook to fix that bug in their SDK.
2) Independently, the issue I was having seems to have gone away after signing out of Facebook in the device's Settings, and then back in. Maybe a glitch in the iOS integration? (The permissions split issue still applies here, however. Make sure you do read first and publish (e.g., publish_actions) separately later, the first time you actually need it.)

Automatic login

I am looking for a way to load simperium without having to present the login view after the first time the user enters his info.
This is what I get if I dont log in after the first time:
Simperium error: bucket list not loaded. Ensure Simperium is started
before any objects are fetched.
This is what I use to init Simperium:
self.simperium = [[Simperium alloc] initWithRootViewController:
_window.rootViewController];
thanks
Consider using OAuth.
OAuth is a system where the user can provide their credentials for a popular service like Google, Twitter, Facebook or other open ID providers.
Rather than caching the credentials on the device, which would be insecure, since getting access to these would give the user access to a large number of systems, OAuth gets the main authentication service to provide a token.
This token gets stored on the device and can be used to login automatically the next time.
The drawback is that it can be quite tricky to set up the first time, since there's quite a lot of complexity going on, not to mention that the standard is quite new so there was some evolution in the specification.
Simperium just needs user credentials to get started (the app id and username/token). The login view is a convenience to get those credentials for you, if you can already obtain them using some other means (like using HTTP auth API: https://simperium.com/docs/reference/http/#auth) then you can directly supply those without using the login view. See methods in https://github.com/Simperium/simperium-ios/blob/develop/Simperium/SPAuthenticator.m

Resources