-
Notifications
You must be signed in to change notification settings - Fork 893
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
2.4.0 breaks custom login provider? #357
Comments
Downloading the sample code again, they still seem to use DeveloperAuthenticatedIdentityProvider : AWSAbstractCognitoIdentityProvider. So not sure what to do here, I guess I just have to revert to the old 2.3.6, as getting this custom identity to work was very complex in the first place. |
YES, same issue. the 2.4.0 version will break my production app. I have a customerSignin Provider based on AWSEnhancedCognitoIdentityProvider @interface CustomIdentityProvider : AWSEnhancedCognitoIdentityProvider
|
I hope there is a transition tutorial for the removed class. |
Same issue, just updated via cocoapods to Fatal: Warning: It would be great if the samples could be updated to reflect the changes in https://github.com/awslabs/aws-sdk-ios-samples I had a look at the changelog, It mentions the deprecated logins issue, but nothing about the https://github.com/aws/aws-sdk-ios/blob/master/CHANGELOG.md @yosuke-matsuda @aws-dpt @behrooziAWS Can someone spare a few mins to update the samples to reflect the new changes when you get a chance? |
You can take a look at the implementation of We are preparing the sample app updates, and it should be available soon. When we update our samples, we'll update this thread. Thanks. |
I can't seem to figure this out. Where do I implement my previous refresh() method? Do I now have to build a AWSCognitoIdentityProviderRefreshTokensRequest instead? Hopefully your samples will help. It's bit daunting that after spending so much time to get custom logins working with Lambda a point update has changed everything it seems. Especially considering this is something the competition is offering with zero implementation and is something almost every app will need, as relying on 3rd party logins is not feasible for a real life app. |
breaking changes like this should not be a point update 👎. Dealing with this same issue myself. What makes it worse is documentation of this breaking change shouldve gone up with the 2.4.0 release :(. |
Normal practice would have been to leave the deprecated method in there still working but flagged as depcricated. To sink the whole sdk like this I don't think is acceptable unless you're on a 0.9 release cycle. |
Did anybody manage to do this? Cause i'm in need to implement it and i can't seem to figure out which methods should i implement of the provider, maybe i should return NO in the isAuthenticated method and then my getIdentityId will be called? |
@guillecom you might want to go with the new user pools, although it's in beta only. https://mobile.awsblog.com/post/TxGNH1AUKDRZDH/Announcing-Your-User-Pools-in-Amazon-Cognito |
Thanks for the advice, here is one that might shed some light on the original issue:
which the implementation of the identity provider manager has this method
I think that this is our new refresh method (altought i never implemented a refresh method in the first place :P) |
I was right, i just managed to implement this, if you implement the logins method of the Remember not to overload |
7 days already and no proper documentation for how to reimplement something that was broken. Considering how huge this SDK you can imagine how agonizing this can get. I wasted various hours already on this to no avail. Rolling back to pre 2.4.0 and scrutinizing every minor update on this repo. |
I agree with everyone else here. Ive spent countless hours debugging and googling and reading aws documentation, until i found this thread. If you make an update like this , atleast provide documentation for something like this , custom developer identity is not a small thing to skip documenting. Whats even more fun is googling around every freaking website to find the older version . .. . great |
I want to take a little bit of time to explain the version numbering convention we use in our SDK. The incremented first digit indicates a total overhaul of the SDK. There is almost no backward compatibility, and you need to completely rewrite your app. This happened when we jumped from 1.x.x to 2.x.x. The second digit indicates minor breaking changes. For example, from 2.2.x to 2.3.0, we started including We release updated API docs with the SDK update. @guillecom used them to implement the credentials provider on his own. We are still working on more detailed documentation with sample apps. They will be available shortly. If API documentation is not enough, and you need more help, please watch out for 2.x.0 releases and evaluate thoroughly before jumping on it right away since they contain some breaking changes. We understand this is not Semantic Versioning 2.0.0 compliant, and this may be one of the reasons some people got confused. We will see if we can adopt Semantic Versioning in our SDK. Thanks, |
@yosuke-matsuda @guillecom I'm no being able to get as far as login in and getting my token and cognito ID. But once I try and do something like query a table it comes back with error:
Before I never had to deal with sts:AssumeRoleWithWebIdentity ? Is this something I need to add now? |
@yosuke-matsuda Might it be easier to get this to work being it on the mobile hub code example where there is a AWSMobileHubHelper that has a AWSSignInProvider. Looking at that code though, I'm not sure how to implement the login() method in order to get the AWSIdentityManager.defaultIdentityManager().loginWithSignInProvider(signInProvider, completionHandler: {(result: AnyObject?, error: NSError?) to be called back? |
Same problem here! |
Just pushed an updated Cognito Sync Demo app to a branch. You should take a look at the implementation of This Cognito Sync sample app seems to be a little behind of the latest AWS SDK updates, and there are many areas where it overlaps with AWS Mobile Hub generated sample apps. We will try to integrate |
@yosuke-matsuda So I now get the token and the identiyID fine, however, once I try and make a dynomdb call I then get an error saying
This does not happen when running 2.3.6 with the same dev identity providers. Not sure if there's some clash with the new identity pools somehow, as I'm not aware of this sts:AssumeRoleWithWebIdentity and why it's being denied when running 2.4.0 and not while running 2.3.6 ? |
@yosuke-matsuda I did create in AmazonClientManager.swift a new function called customLogin:
but I'm getting this error compile error:
It looks like is trying to find this identityId in my Federated Identities panel, but since it doesn't exists, is shows this error. What it missing in order to have this identity Id created? |
@yosuke-matsuda If I change the Trust Relationship to
it does seem to work now... however, not sure what these trust thing is all about as I didn't need that under 2.3.6 |
@helloniklas Are you passing @Stradix The error you are encountering does not seem to be related to the |
@yosuke-matsuda right, that seems to work now, missed that these were set to nil in your example. |
@yosuke-matsuda However, I'm now running in to some other issues I didn't have with 2.3.6. If I first log in with DeveloeprAuthenticated ID, then logout, and try and log in with Facebook, it won't work until I completely shut the app down and login. Seems the logout doesn't really work properly. Before I could clear the logins but now with 2.4.1 I set keychain etc to nil and
But this somehow doesn't work properly. Even after loging out then authenticating with Facebook, when I then try and do a request, it still tries to refresh the DeveloperAuthenticated thing. And vice versa, if I first login Facebook, then logout, when then loging in with DeveloperAuth, it still tried to refresh the Facebook manager, although I've set the AWSCognitoCredentialsProvider to use the DeveloperAuth. |
@yosuke-matsuda I also now get an error the first time the app is installed and try to login,
this causes the app to crash. It then works the second time around. Seems 2.4.1 is very flakey? Or I'm missing something in the implementation. |
@helloniklas The reason why you needed to open up your trust relationship above was likely because you were passing in roles for a different identity pool. Since the pool didn't match what was in the amr, requests were getting rejected. Now that you are not passing in roles (you've set them to nil) it is using the correct roles that are associated with your pool. You should always lock down your trust relationship, otherwise anyone using Cognito Identity can assume your roles. Without seeing what you are doing in your IdentityProviderManager, it is difficult to tell why you are still authenticating as dev auth after logging out. Do you pivot to setting the Facebook token in the logins map after logging out and is the Facebook token the only item in your logins map? With your app crash, are you correctly setting the defaultServiceConfiguration? See Step 4 for an example. |
And here is the swift documentation: To use developer authenticated identities, implement your own identity provider class which extends AWSCognitoCredentialsProviderHelper.
To use this identity provider, pass it into AWSCognitoCredentialsProvider as shown in the following example:
If you want to support both unauthenticated identities and developer authenticated identities, override the logins method in your AWSCognitoCredentialsProviderHelper implementation.
If you want to support developer authenticated identities and social providers, you must manage who the current provider is in your logins implementation of AWSCognitoCredentialsProviderHelper.
|
@behrooziAWS Wouldn't it be better to add this to your official docs, they are very outdated, and downloading samples from mobile hub is even worst. |
I've passed this content to the docs team. When they incorporate it, I will resolve this issue. |
@behrooziAWS Can I please trouble you for a sample on how to use Digits with Cognito? I am encountering the same problem with trying to use Digits with the new SDK. I followed the existing examples for 2.36 and basically stuck on this step to set the logins :( Please help. |
@georgel likely you will need to implement an IdentityProviderManager that does something like this:
|
@behrooziAWS Thank you, David and all the helpful folks on this thread. I finally got it to at least login with Digit. Can someone please give me a tip on how to go from un-auth user to an auth-ed user. When a user first open the app, they are assigned a un-auth identityId. After they login in, I am able to get the correct authed identityId. But when the app relaunches, the credentialProvider.identityId is still the un-auth id. Here's what I piece together from all the helpful tips above. Please let me know if I am missing a step somewhere :) An IdentityProviderManager:
Invoked by
If I may make a request. I am guessing it's challenging to keep docs up to date with each release. It would be nice if the SDK sample contained tests for the supported public providers and a sample custom provider. It would be much easier to use a test as the reference for me. |
@georgel Once an identity becomes authenticated, you cannot get credentials against it unless you provide a valid token. The recommended approach is to instantiate your credentials provider in your |
Thank you for your patience! The documentation has been updated for using developer authenticated identities with iOS SDK 2.4.x. http://docs.aws.amazon.com/cognito/latest/developerguide/developer-authenticated-identities.html We will work to update the documentation for other identity providers, in the meantime there are a few examples of how to integrate with Facebook and Twitter in this thread. |
If I leave out the auth roles from the
If I include the roles:
Also in the developer authenticated identities Swift example, the identity provider is implemented using Objective-C which is of little help. It would be great to get the meat of that example in Swift. |
I seemed to have solved my problem for my implementation of a Developer Authenticated only support. For those who were having similar troubles to me here is my setup. Open to getting this cleaned up if anyone has any suggestions. (Swift 3):
|
First me let me get this out of the way: The AWS SDK is huge, VERY HARD to follow (if you practically didn't write it), IS NOT very well documented and has many bugs (many which I have uncovered). To the iOS AWS SDK Team:
With that being said, after finally deciding to unpin my AWS SDK from v2.3.6 and dedicating some time to getting the latest SDK version working heres what I found after spending nearly ~8+ hrs dissecting the AWS SDK - alot of which was harder to debug in XCode due to all the callbacks implemented in the code. Enjoy 🎉! To provide federated identities with cognito at the most basic level what has to happen is that your backend has to make a call to GetOpenIdToken to get a Cognito token for your Cognito Identity Pool. This token is returned to your iOS app and it is this token that will be used to authenticate with AWS. To Handle Developer Federated Identities in the iOS Client the following Must Be Done1. Create a Custom Identity Provider that SubClasses AWSCognitoCredentialsProviderHelper //
// WinkIdentityProvider.h
// Wink
//
// Created by Adonis Peralta on 5/26/15.
// Copyright (c) 2015 TouchSix, Inc. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <AWSCore/AWSIdentityProvider.h>
@interface WinkIdentityProvider : AWSCognitoCredentialsProviderHelper
@end
//
// WinkIdentityProvider.m
// Wink
//
// Created by Adonis Peralta on 5/26/15.
// Copyright (c) 2015 TouchSix, Inc. All rights reserved.
//
#import <AWSCore/AWSCore.h>
#import "WinkAPI.h"
#import "WinkIdentityProvider.h"
#import "Session.h"
#import "AWSToken.h"
#import "Person.h"
@interface WinkIdentityProvider ()
@property (nonatomic, copy) NSString *awsToken;
@end
@implementation WinkIdentityProvider
- (AWSTask *)token
{
return [[AWSTask taskWithResult:nil] continueWithBlock:^id _Nullable(AWSTask * _Nonnull task) {
return [self refresh];
}];
}
// call to backend, called through entry point
- (AWSTask *)refresh
{
if (![WinkAPI sharedManager].session) return [AWSTask taskWithError:[NSError errorWithDomain:kWinkErrorDomain code:1 userInfo:@{NSLocalizedDescriptionKey:@"unable to refresh AWS token, no valid WinkAPI session."}]];
AWSTaskCompletionSource *task = [AWSTaskCompletionSource taskCompletionSource];
[[WinkAPI sharedManager] refreshAWSTokenWithCompletion:^(AWSToken *token, NSError *error) {
if (error) {
[task setError:error];
return;
}
self.identityId = token.identityId;
self.awsToken = token.uid;
[task setResult:self.awsToken];
}];
return task.task;
}
// tells aws in its api call if your user is authenticated or not - this correlates with the authRoleArn and unAuthRoleArn parameters of your identity pool
- (BOOL)isAuthenticated
{
if ([WinkAPI sharedManager].session) return YES;
return NO;
}
// override of the clear method of the identity provider so you can clean up your custom identity provider
- (void)clear
{
[super clear];
self.awsToken = nil;
self.identityId = nil;
}
@end 2. Initialize and setup your AWS Credentials in a class implementation of your choosing // AWSHandlers.m
#import "WinkIdentityProvider.h"
#import "AWSCore.h"
#import "AWSS3.h"
@interface AWSHandlers ()
@property (nonatomic, strong) AWSCognitoCredentialsProvider *awsCredentialsProvider;
@property (nonatomic, strong) AWSS3TransferManager *s3TransferManager;
@end
@implementation AWSHandlers
- (void)setupAWS
{
// instantiate our custom identity provider
WinkIdentityProvider *winkProvider = [[WinkIdentityProvider alloc] initWithRegionType:AWSRegionUSEast1
identityPoolId:@"identity-pool-id-here"
useEnhancedFlow:YES
identityProviderManager:nil];
// instantiate the credentials provider with our customer identity provider
self.awsCredentialsProvider = [[AWSCognitoCredentialsProvider alloc] initWithRegionType:AWSRegionUSEast1
identityProvider:winkProvider];
AWSServiceConfiguration *defaultAWSConfig = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSEast1 credentialsProvider:self.awsCredentialsProvider];
[[AWSServiceManager defaultServiceManager] setDefaultServiceConfiguration:defaultAWSConfig];
// setup a s3 transfer manager
self.s3TransferManager = [AWSS3TransferManager defaultS3TransferManager];
// change the verbosity level of the aws sdk if you choose
//[AWSLogger defaultLogger].logLevel = AWSLogLevelVerbose;
}
// call on app logout AND login! If not, cached credentials which may or may not be valid can be used during an app reinstall, or first loading of your app (not resuming from background)
- (void)invalidateAWSCredentialsAndHandlers
{
[self cancelAllCurrentS3Operations];
[self.awsCredentialsProvider clearKeychain];
self.awsCredentialsProvider = nil;
self.s3TransferManager = nil;
} Custom Identity Provider1. Initialize your custom identity provider via initWithRegionType:identityPoolId. Do not use the other methods that specify a identity provider manager as an identity provider manager is for when not using developer provided identities. 2. If the token you provided is invalid or EXPIRED the AWS SDK will attempt to refresh your token (via getIdentityId method) ONE more time. After that IF IT FAILS again the call that triggered the getting of AWS credentials (for example downloading an AWS image) will fail. 3. The Custom Identity Provider (BOOL)isAuthenticated method is needed to tell AWS in its api call if your user is authenticated or not. This correlates with the authRoleArn and unAuthRoleArn. 4. Override the Custom Identity Provider -(void)clear method to do any clean up of your custom identity provider variables if necessary. AWSCognitoCredentials Initialization InfoAfter initializing and seting up the aws cognito credentials as described above in step #3 here are some quirks to know of about the AWS SDK:
**If you do not clear the provider keychain on login, the AWS SDK will attempt to use the keychain stored credentials instead of calling your backend for a valid token again. Failing to do so has very bad implications:
Update: The above post has been updated to factor a misunderstanding about the IdentityProviderManager class. Initially I believed it was part of the developer identity provider flow but it is not. This simplifies many of the findings I had found previously in regards to the use of enhancedFlows vs non-enhanced throughout the authentication process. |
Hello, |
Hi @ivanfervar,
Did you read my post above above. Its a bit long and detailed but will definitely explain what's happening behind the scenes and should help you out.
… On Jan 11, 2017, at 7:33 AM, ivanfervar ***@***.***> wrote:
Hello,
To login with Developer Authenticated Identities in SDK AWS v2.4.16 I have a ILDeveloperAuthenticatedIdentityProvider (:AWSCognitoCredentialsProviderHelper
) where has implemented “(AWSTask<NSString *> *)token” among others like AWS Doc explain, but this “token” function never called.
Why could this be happening?
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.
|
@Donileo i don't suggest you use the approach that you suggested
is more of an approach used in older release (2.3.6 and before). It doesnt apply and will not work well if you use a 2.4.0 or higher version of sdk. From 2.4.0 the logins method should always return a current token. If you cache the token then it will eventually expire and the sdk will only call logins when it is refreshing the credentials. I suggest you implement it the way @behrooziAWS suggested a couple of comments before yours by just overriding the method |
@karthiksaligrama the approach I put above is based on analyzing how the SDK currently works in 2.4.0. I am overriding the logins method in the IdentityProviderManager not the IdentityProvider. In the SDK, when using the enhanced flow (non-api) the SDK will call the IdentityProviderManager's login method after it refreshes the token via the (getIdentityId call of the identityProvider - making a backend call) from the IdentityProvider. As far as what I'm noticing thats what I'm supposed to do. Get a valid token, store it in [WinkAPI sharedManager].session. When the token expires (an expiration error condition happens in the SDK) my Identity provider will refresh the token and my [WinkAPI sharedManager].session will have the new token. Then the logins method in my provider manager will return a valid token. I have not been seeing any issues whatsoever with my method. Also, if you override the - (AWSTask <NSString*>) token that method doesn't even get called unless you are in the non-enhanced flow of the IdentityProvider which by default you are not. Keep in mind the IdentityProviderManager MUST be implemented and passed in when initializing your custom identity provider via initWithRegionType:identityPoolId:useEnhancedFlow:identityProviderManager:. Please see the lines starting with 262 in AWSIdentityProvider.m:
|
@Donileo i get that. You really shouldnt be setting the identityProviderManager at all. You should just extend the When ever you are using developer authenticated identities you need to use the constructor.
|
@karthiksaligrama what is the IdentityProviderManager for then? Yes, if you were to use that method above only and not provide an identityProviderManager then yea you should implement the tokens method in your identityProvider. As far as my code, I did implement an IdentityProviderManager and of course when you do you should implement the logins method in your provider manager. Can you please explain whats wrong with my method. I believe both are fine. Seems like you are implying the token returned by the IdentityProvider tokens method is not the same as the one returned in the logins method of the IdentityProviderManager. As far as my backend, yes my backend does call GetOpentIdTokenForDeveloperIdentity and provide my client code with a new AWS token essentially refreshing my token, it does it successfully when it expires. What triggers the call? The AWS SDK detects when the token has expired, and places my backend call to refresh/provide a new token by calling GetOpentIdTokenForDeveloperIdentity. Don't see anything wrong there. |
The IdentityProviderManager is for when you are not using developer provided identities. If you are using developer provider identities at all, then the logins method on AWSCognitoCredentialsProviderHelper serves the role as the IdentityProviderManager. |
@behrooziAWS got it :). As far as my code it still works, just that my refresh token call should also be in the token method and theres no need for my Custom IdentityProviderManager. Thanks! I'll update the post I made up above. |
@behrooziAWS Where is this differentiation on Are there any code samples that demonstrate how to use either (or both) of them as intended? |
@kdbertel @behrooziAWS also if the AWSIdentityProviderManager is not part of the developer provider identities flow at at all why is it being asked for on the initialization to the AWSCognitoCredentialsProviderHelper? Please see method: |
@Donileo It is not required. If you have an identity provider manager that implements all of your other non developer authenticated providers, you can call it in the logins method in your AWSCognitoCredentialsProviderHelper. |
To avoid further confusion, no one from AWS will continue to respond to this thread. There are several implementations in the comments that fail for certain edge cases, don't properly refresh tokens, are more complicated than necessary or are for unrelated issues. Too many people are arriving at this thread, not following the official guidance and ending up with issues. The official guidance is here: http://docs.aws.amazon.com/cognito/latest/developerguide/developer-authenticated-identities.html Please open a new issue if you have issues with the official guidance. |
This was either hard to find or did not exist until recently. Thank your for putting this up here.
… On Jan 12, 2017, at 1:49 PM, David Behroozi ***@***.***> wrote:
To avoid further confusion, no one from AWS will continue to respond to this thread. There are several implementations in the comments that fail for certain edge cases, don't properly refresh tokens, are more complicated than necessary or are for unrelated issues. Too many people are arriving at this thread, not following the official guidance and ending up with issues. The official guidance is here: http://docs.aws.amazon.com/cognito/latest/developerguide/developer-authenticated-identities.html Please open a new issue if you have issues with the official guidance.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.
|
@behrooziAWS I'm not stating that it "is" required. Simply, if its not, why surface it up so high up to designated initializer of the AWSCognigoCredentialsProviderHelper. The fact that its there makes it seem that it is. The official docs? Let us all hope they are good now :/. |
@behrooziAWS sorry! but your comment is not serious: Firstly, I know this link because in a issue ticket, a AWS support guy told my team we should try with @Donileo information. After your comment, that response mysteriously disappeared. Secondly, Open new issue? we have opened dozens tickets about cognito and IOS, We always receive the same reponse, "are you use clearKeychain? are you instantiating 2 sync clients? ahh OK!!!! I have passed the information to the Cognito Team". I opened a ticket in October and the last weekend (3 months) the support team guy ask us again... "are you use clearKeychain?" OMG!!!!! Do you understand why people are arriving at this thread? |
@drsromero exactly. Theres a reason why this thread exists and is the amount of comments you see; horrible documentation from AWS. My original post detailing how to properly implement the auth flow was the best that I could implement based on what I knew, and what I discovered debugging the SDK. I also figured I'd try and help others given how crazy this issue had become. After they provided new info (that the manager isn't for dev authenticated flows) it changed a lot of the information I had posted and the post is now updated to match this simpler flow. But if the manager is used then all the info in my original post all applies again. Again its not a coincidence this thread is what it is. Btw, looking at the docs @behrooziAWS posted it seems that the IdentityProviderManager is to be used during dev federated identities when you want to provide auth for the standard providers as well. He seemed to imply the manager is not part of the flow at all, which definitely contradicts the link he posted. Once you add the manager, like in this case, I'd say my original post applies again. |
God, after spending HOURS trying to solve "Invalid token" error I've noticed that using wrong initializer for AWSCognitoCredentialsProvider. It should be initWithRegionType:identityProvider: (not initWithRegionType:identityPoolId:identityProviderManager: !!!). Also, there is no any difference between [logins] and [token] overriding for developer identities. And, yes, it's better to pass self.identityProviderName to get logins key for developer identities since it returns "cognito-identity.amazonaws.com" Hope it helps someone in trouble... |
So I spent ages getting a custom login provider to work. I have a class BYOIProvider extending AWSAbstractCognitoIdentityProvider based on some AWS sample. This was all working fine. However, upgrading to 2.4.0 the AWSAbstractCognitoIdentityProvider is no longer available? Do I have to rewrite this code now?
The text was updated successfully, but these errors were encountered: