Describe the bug
Configuring the mobile client (version 2.7.3) for a developer-authenticated login using the federatedSignIn method does not result in an authenticated client.
To Reproduce
Steps to reproduce the behavior:
{
"UserAgent": "aws-amplify/cli",
"Version": "0.1.0",
"CredentialsProvider": {
"CognitoIdentity": {
"Default": {
"PoolId": "POOL_ID",
"Region": "REGION"
}
}
},
"IdentityManager": {
"Default": {}
},
"AppSync": {
"Default": {
"ApiUrl": "API_URL",
"Region": "REGION",
"AuthMode": "AWS_IAM"
}
}
}
AWSMobileClient, the client will automatically assume an unauthenticated role, as specified in the identity pool configuration.federatedSignIn method. Here's an example for the CLI:aws cognito-identity get-open-id-token-for-developer-identity --identity-pool-id IDENTITY_POOL_ID --logins [email protected] --token-duration 3600
federatedSignIn method like so:AWSMobileClient.sharedInstance().federatedSignIn(providerName: "login.com.test", token: "TOKEN_FROM_STEP_4") { (userState, passedError) in
if let error = passedError {
print("Federated Sign In failed: \(error.localizedDescription)")
}else{
print("federated sign in succeeded: \(passedError?.localizedDescription ?? "no error")");
let identityId = AWSMobileClient.sharedInstance().getIdentityId()
}
}
getIdentityId method will not return a new identityID and the identityID returned does not have the authenticated role specified in the identity pool. Of course, calling an IAM-protected service (for me, AppSync), results in an 401 response.Which AWS service(s) are affected?
Cognito
Expected behavior
The client should become authenticated after passing a valid token to the federatedSignIn method.
Environment(please complete the following information):
Device Information (please complete the following information):
Additional Information
Switching to User Pools, the app behaves as expected. An authenticated role is assumed upon successful login and our protected resources are available. Unfortunately, we need IAM auth (and developer authenticated identities) for unauthenticated access to AppSync.
Hello @adamup928
Sorry that you are having issues using AWSMobileClient, the getIdentityId() method which you are calling will asynchronously fetch the identityId for the given logins map. It returns an object of type AWSTask<String> which on completion would have the identityId or an error.
To help us debug this issue better, could you please provide with what is the error message that you are getting?
Could you replace this code:
let identityId = AWSMobileClient.sharedInstance().getIdentityId()
with
AWSMobileClient.sharedInstance().getIdentityId().continueWith { task in
if let error = task.error {
print("error: \(error.localizedDescription) \((error as NSError).userInfo)")
}
if let result = task.result {
print("identity id: \(result)")
}
return nil
}
Hi @rohandubal -
Thanks for your message. No error is generated in that snippet. It returns with an identityId that acts as if it's unauthenticated. The returned identityId does not match the one returned with the generated token using the AWS CLI's get-open-id-token-for-developer-identity method.
If I use the AWS web console's cognito identity browser, I can see the SDK's returned identityId but there is no linked account (which was passed in as a parameter to the CLI's get-open-id-token-for-developer-identity method).
Let me know if I can send any other information your way. Hopefully this is just a misunderstanding of the documentation on my part!
Hello @adamup928
Thanks for getting back. That is interesting, once you provide a token, the un-authenticated identity should be cleared.
This can be seen in this method:
From what I understand based on above information, you are in a signedIn state with an unauthenticated state, which should not happen.
I will try to reproduce this issue on my side. But I am thinking this might be some issue of the way it is used in the app.
Are you assigning a custom role to the identity provider for developer authenticated identity?
Thanks,
Rohan
Thanks, @rohandubal - I can confirm the same identity is present before and after the federatedSignIn call (and that the userState of the client is .signedOut immediately before I call it, and .signedIn after it returns).
Even once I am ".signedIn," calls to protected resources fail (401 unauthorized), but the same calls succeed if I switch to a userpool sign-in, just to test that the IAM role is being assigned appropriately to an authenticated user.
Am I maybe missing a trust relationship that needs to be defined specifically for developer authenticated identities? I believe I followed everything in the documentation here but maybe there's another step. Currently, for the roles I would like an authenticated user to assume, I have cognito-identity.amazonaws.com as a trusted entity and ForAnyValue:StringLike | cognito-identity.amazonaws.com:amr | authenticated for the conditions, if that helps in any way.
Hi @rohandubal -
Here's how I'm setting up the mobile client and attempting the federated login. The console shows the same identityID before and after calling federatedSignIn:
public func exampleClient() {
AWSMobileClient.sharedInstance().initialize { (userState, error) in
if let userState = userState {
print("userState at init " + userState.rawValue)
} else if let error = error {
print(error.localizedDescription)
}
}
let identityId = AWSMobileClient.sharedInstance().getIdentityId()
print("initial identityID: \(identityId)");
AWSMobileClient.sharedInstance().federatedSignIn(providerName: "com.login.test", token: "INSERT_TOKEN_HERE") { (userState, passedError) in
if let error = passedError {
print("Federated Sign In failed: \(error.localizedDescription)")
}else{
print("federated sign in succeeded: \(passedError?.localizedDescription ?? "no error")");
DispatchQueue.main.async {
AWSMobileClient.sharedInstance().getIdentityId().continueWith { task in
if let error = task.error {
print("error: \(error.localizedDescription) \((error as NSError).userInfo)")
}
if let result = task.result {
print("identity id: \(result)")
}
return nil
}
}
}
}
}
@rohandubal - just wanted to add here that I was able to successfully implement developer authenticated logins with the Amplify Javascript SDK. Unfortunately, it didn't provide me any insight into why the iOS SDK is failing to login with the same identity pool, generated tokens, etc.
Some progress. Here are some notes that hopefully will help somebody going down the same path with developer-authenticated identities.
[[AWSMobileClient sharedInstance] interceptApplication:application didFinishLaunchingWithOptions:launchOptions] (this is a mixed objective-c/swift project) inside the application delegate and just relying on AWSMobileClient.sharedInstance().initialize later on stopped the guest identityId from persisting across a call to federatedSignInfederatedSignIn for the providerName parameter is cognito-identity.amazonaws.comNow, when I call getIdentityId(), the generated request body is strucutured like this:
{"IdentityPoolId":"REGION:IDENTITY_POOL_ID","Logins":{"cognito-identity.amazonaws.com":"TOKEN_HERE"}}
but the error message in response is "Invalid login token. Can't pass in a Cognito token."
@rohandubal - Any ideas from here?
Hello @adamup928
Sorry was caught up in another issue. I will work on this and have an update soon.
Thanks,
Rohan
Hello @adamup928
I identified the issue. The issue is missing spec for specifying Cognito Identity ID in the federatedSignIn API. Developer Authenticated Identities use a different flow as compared to other identity providers like Social providers.
I am working on a solution to add this field in the API and make it work. This will be released in a future release.
Thanks for your patience!
Best,
Rohan Dubal
Thanks for the update, @rohandubal.
Adam
Hi @adamup928 ,
We have just released version 2.8.2 of the SDK. Please check if this fixes the issue for you.
Hi @rohandubal and @minbi -
Version 2.8.2 works great, and I'm able to successfully authenticate.
Thanks,
Adam
@rohandubal - just wanted to add here that I was able to successfully implement developer authenticated logins with the Amplify Javascript SDK. Unfortunately, it didn't provide me any insight into why the iOS SDK is failing to login with the same identity pool, generated tokens, etc.
Can you share your code for this? I'm struggling with JS authentication!
Most helpful comment
Hello @adamup928
Sorry was caught up in another issue. I will work on this and have an update soon.
Thanks,
Rohan