Describe the bug
If a CustomAuth flow is interrupted (by an app restart, e.g.), the CustomAuth flow cannot be completed successfully
To Reproduce
Steps to reproduce the behavior:
AWSMobileClient.default().signIn(username: username, password: "dummyPassword")AWSMobileClient.default().confirmSignIn(challengeResponse: "<Challenge Response>"...Observed Behavior
AWSMobileClient returns error 'Please call signIn before calling this method.'
Expected Behavior
AWSMobileClient should be able to continue/complete the original call to signIn. Maybe the Session needs to be persisted, instead of kept in memory?
Unique Configuration
{
"IdentityManager": {
"Default": {}
},
"CredentialsProvider": {
"CognitoIdentity": {
"Default": {
"PoolId": "<redacted>",
"Region": "us-east-1"
}
}
},
"CognitoUserPool": {
"Default": {
"PoolId": "<redacted>",
"AppClientId": "<redacted>",
"Region": "us-east-1"
}
},
"Auth": {
"Default": {
"authenticationFlowType": "CUSTOM_AUTH"
}
}
}
Areas of the SDK you are using (AWSMobileClient, Cognito, Pinpoint, IoT, etc)?
AWSMobileClient
Environment(please complete the following information):
Device Information (please complete the following information):
Relevant Console Output
LOG OUTPUT FROM 1st APP RUN
2020-05-20 10:17:58:261 APPNAME[4274:2759335] Configuring SignInProvider : CognitoUserPool.
2020-05-20 10:17:58:262 APPNAME[4274:2759335] Registering SignInProvider AWSCognitoUserPoolsSignInProvider from awsconfiguration.json.
2020-05-20 10:18:13.785914-0500 APPNAME[4274:2759553] Attempting signIn with email and dummyPassword
2020-05-20 10:18:13:863 APPNAME[4274:2759335] Request headers:
{
"Content-Type" = "application/x-amz-json-1.1";
Host = "cognito-idp.us-east-1.amazonaws.com";
"User-Agent" = "aws-sdk-iOS/2.13.1 iOS/13.4.1 en_US";
"X-Amz-Date" = 20200520T151813Z;
"X-Amz-Target" = "AWSCognitoIdentityProviderService.InitiateAuth";
}
2020-05-20 10:18:13:863 APPNAME[4274:2759335] Request body:
{"UserContextData":{"EncodedData":"eyJwYXlsb2FkIjoie1widXNlcm5hbWVcIjpcInN0ZXBoZW4uci5ncmF5KzI1QGdtYWlsLmNvbVwiLFwiY29udGV4dERhdGFcIjp7XCJDYXJyaWVyXCI6XCJBVCZUXCIsXCJBcHBsaWNhdGlvblZlcnNpb25cIjpcIjAuMS4wLTM2XCIsXCJIYXNTaW1DYXJkXCI6XCJ0cnVlXCIsXCJQaG9uZVR5cGVcIjpcImlQaG9uZTEyLDNcIixcIkRldmljZUlkXCI6XCIxOTcyZThmNi00OThjLTQ5NzAtOTEzNy1lMGMyNGJkZWNmMzhcIixcIk5ldHdvcmtUeXBlXCI6XCJDVFJhZGlvQWNjZXNzVGVjaG5vbG9neUxURVwiLFwiU2NyZWVuV2lkdGhQaXhlbHNcIjpcIjExMjVcIixcIlBsYXRmb3JtXCI6XCJpT1NcIixcIlNjcmVlbkhlaWdodFBpeGVsc1wiOlwiMjQzNlwiLFwiQXBwbGljYXRpb25UYXJnZXRTZGtcIjpcIjgwMDAwXCIsXCJBcHBsaWNhdGlvbk5hbWVcIjpcImNvbS5jcm93ZG5vaXNlLkNyb3dkTm9pc2VNb2JpbGVcIixcIkRldmljZU9zUmVsZWFzZVZlcnNpb25cIjpcIjEzLjQuMVwiLFwiRGV2aWNlRmluZ2VycHJpbnRcIjpcIkFwcGxlXFxcL2lQaG9uZVxcXC9pUGhvbmUxMiwzXFxcLy06MTMuNC4xXFxcLy1cXFwvLTotXFxcL2RlYnVnXCIsXCJUaGlyZFBhcnR5RGV2aWNlSWRcIjpcIjg1RDEzMzJELUEwNzctNDQ3My1BRkNBLTA3OUNFQzMwRTFCNVwiLFwiRGV2aWNlTGFuZ3VhZ2VcIjpcImVuLVVTXCIsXCJDbGllbnRUaW1lem9uZVwiOlwiLTA1OjAwXCIsXCJCdWlsZFR5cGVcIjpcImRlYnVnXCIsXCJEZXZpY2VOYW1lXCI6XCJTdGVwaGVuJ3MgaVBob25lIDExIFByb1wifSxcInVzZXJQb29sSWRcIjpcInVzLWVhc3QtMV9salVJM0w5NWlcIixcInRpbWVzdGFtcFwiOlwiMTU4OTk4Nzg5Mzg1NFwifSIsInZlcnNpb24iOiJJT1MyMDE3MTExNCIsInNpZ25hdHVyZSI6IndMclNVNGR4a2FvZFA3QSt3R21hY2VhN1dlUk1Lclg3TG9KXC81UU4wOWZvPSJ9"},"ClientMetadata":{"cognito:deviceName":"iPhone 11 Pro","cognito:bundleShortV":"0.1.0","cognito:idForVendor":"85D1332D-A077-4473-AFCA-079CEC30E1B5","cognito:bundleVersion":"36","cognito:bundleId":"com.APPNAME.APPNAMEMobile","cognito:model":"iPhone","cognito:systemName":"iOS","cognito:iOSVersion":"13.4.1"},"AuthParameters":{"SRP_A":"8b63f28694412c040b429517fe6566552ac3ba1fd984da59a4b0f9d87622cd208019268d92cc9c57306555959704bfcc8a8f603caaaf31dd9d3c3276f7979a0e70b5c74a5ed90061923dee9006d2c56065a5510823e2a1e9e6f50f01e2283ad44de124b91e5a2ee51968e0ef63b146c66ea92e105a3b012aab29820cec77be72af5d889c9ea7a8838ee34df83adea053d586fcd9f14cf91c51717cbb2b1c2177029799c83caf0a552c89518ae110892793fea717f61ecba87d7a3a3c0282ad10b8519dd08b9afc643df6b4419ff3738156e48d820e1785e1a29debb9d1038bb5cfcac7928605e19edade1222e2d731b8fb4733ca0009b56249519a6e68d6708a0e0feb4e9892b08222e36d6c8526926ce51df3e277d1f0054c0bd83307973e7d01c9a8a73ff47bba57ad6675fb3250e3558beeb66940cf213b9869bb8c5b7e26d62311e0d1652af0cd70c3e5812dfd4ab95f5969b7d5e64b66b6a35d9a31a696cf9bc8d44f76cc34b0a9586d048ac2714471884df08470fc429230467dac4786","CHALLENGE_NAME":"SRP_A","USERNAME":"<redactedEmailAddress>"},"AuthFlow":"CUSTOM_AUTH","ClientId":"<redacted>"}
2020-05-20 10:18:15:036 APPNAME[4274:2759547] Response headers:
{
"Content-Length" = 1383;
"Content-Type" = "application/x-amz-json-1.1";
Date = "Wed, 20 May 2020 15:18:14 GMT";
"x-amzn-requestid" = "f7e4e7dd-cc9e-42f3-901e-e48b64d77a89";
}
2020-05-20 10:18:15:036 APPNAME[4274:2759547] Response body:
{"ChallengeName":"CUSTOM_CHALLENGE","ChallengeParameters":{"USERNAME":"255c05e6-1d98-48dc-8c07-510dc6ac70aa","email":"<redactedEmailAddress>"},"Session":"R9gJToJufqLzsZJVdZhJbUV7Jt4Reb5USC5qTJFD8NmE4B4HcR75Qel60DrSpfD4fqqjKYhvorxXZtySE8QJDPvZ3Kb1PGv0oNR_pkUmBtg5-eMtm0jgcKhCG9WvAvb3Brg3gz4bqRv1ZMnnlPdGWq6UJgoRPPJY6bwxbNd4BYl2e7O2WU9sCN20A13tiDwhE4ndBkNqYaR1eeissfOANJLoAlMbNJsiuP2wTFRnrfqtH11LDfSB-zZCkbieHmWLDYTU7Y6Ap1iNQfRg6apkjT6-pBgBlPeyoBQUxOou-xDI1u1H-6WyXaUd83eT20sEZRJtOR_aP5Ki_nnwgXeZdWbgxhwZp2XyTN1S6W3oDguQFpskpRHhAkYrfelFU5LtM0MRRgCthvU92qII0fmclDkqjgUyyEod6eJXjxy9fioOv-BvlOSfPwGWyPPjGL8o0s9tNkgNyzVhyc9QZ2yOaW9g3-SNZBTtNvnn60HbKH58nvlGhXnw306GVHiZsOyc2u59t4xCs91eIJky_XFg_-3xNwlqD_UPJwFGeXirSB_oR20zwOHdiacIbYjToFsl-14UFAUdxv70rrZ97_iPb4ZSCcY8CzkuZSL4ZFvtjl7_lN93YZqT3qyra_pMK5nI2YcIOIxYqn91Dga_I8QAhGO22XH2aWNkXCtNRVBrJdF1WMePay2Jq9Wb8WtjzHUnd7Hvy4RxoVISkin0Novdm4w9vCspdentRe-eBArxEkd2veJHlUpH9lnFWUG4YWbLi-1lKdQOi4VQEJsoSYq_pbd4cno4MXHc8FiNUUcOqXLwbT9IMcn98V_zGT-bznfxrNn_sY9AgEoLR7AMEx-wKwPj_EAR6PVZsdo4egV_vBiXs5bNJx22e-4rHzsWVEA5k6XrVCZ00t7kKBw0uWxmvWnpz6iltWimlRm6XaUOEom4pCExtVIfS6HY7FEsVct5gE3ughz4ssXQ5SAEqAyNC5f0sTRhcTtOji8FfU3gvkXl600X0TFMxluduGini_dGmFA9Zd5haWxE8PPNWToMhKxyUmeNZwAV6w8OHFP2-6oeAEE1bdb4V_0GnilRpizI8yumTN1bNyZds0oyKo68DILmTjPoi10v2pyH4COaavbQv-aoP2cWzF8JjaBbxkFb3MkQxqrAYWHa_7QnP6ltCR-ehN1PurGY6knmX-AiaryD_feCStU0nB73SeOwJ_xbKJJLng"}
2020-05-20 10:18:15.039986-0500 APPNAME[4274:2759553] AWS responded with signInState: customChallenge
LOG OUTPUT FROM 2nd APP RUN
2020-05-20 10:18:28:814 APPNAME[4277:2760029] Configuring SignInProvider : CognitoUserPool.
2020-05-20 10:18:28:815 APPNAME[4277:2760029] Registering SignInProvider AWSCognitoUserPoolsSignInProvider from awsconfiguration.json.
2020-05-20 10:18:39.340814-0500 APPNAME[4277:2760064] Attempting confirmSignIn with challengeCode
2020-05-20 10:18:39.341572-0500 APPNAME[4277:2760066] Please call `signIn` before calling this method.
2020-05-20 10:18:39.347165-0500 APPNAME[4277:2760067] APPNAMEKit.AWSSignInError(0)
Hey @srgray
Thanks for reaching out. At the moment, I believe that we do not plan to support this use case for our authentication flows.
As a user of a native iOS application, if the app crashes between entering my credentials and a custom auth challenge I would expect that when I re-launch the application that I would have to re-enter my credentials. Right?
Similarly, I would expect this behavior if I were attempting to log into a website via a browser which required 2FA, right?
Yes, I understand your reasoning.
Here's a little more detail about our setup:
We use a Lambda flow similar to: https://aws.amazon.com/blogs/mobile/implementing-passwordless-email-authentication-with-amazon-cognito/ to implement custom auth.
When user requests this 'magic link email' in mobile app (the first step in custom auth, where I use AWSMobileClient.signIn(username, "dummyPassword), that triggers our Lambda backend to send an email to the user that contains a direct link back into the app. That direct link has the challenge code embedded so that the app can extract it and complete the auth challenge without user interaction.
So, in this use case, it's a nice feature to have the user be able to tap on that link and complete custom auth automatically, even if the app has restart since the custom auth process was begun.
Thank you so much for taking the time to explain to us your use case!  I now understand why you’d want such a feature, and it makes sense, but in talking with the team, I don’t expect us to pick up this feature any time soon for AWSMobileClient, if ever.
As a workaround, we brainstormed around how you’d be able to work around this.
To summarize your system design for Custom Auth (and please correct me if I’m wrong):
The problem occurs because in Step 4, the app may have been backgrounded too long, or the app crashes, etc..
So, as a work around, in Step 4, AFTER parsing the payload, we could:
public func signIn(username: String,
password: String,
validationData: [String: String]? = nil,
completionHandler: @escaping ((SignInResult?, Error?) -> Void))
I think this approach will work, and best of luck! Let us know how it goes!
Thanks again!
Thank you for the suggested workaround. We are going to try this out and I will report back.
@srgray did any of the workarounds work?
We weren't able to get this workaround working. The main issue is that we couldn't get AWS Cognito backend to make the connection between the first and second calls to signIn/initiateAuth, probably due to the stateless nature of Cognito/Lambda. So, the second call to signIn (even though we provide a flag that indicates it's the second call), is basically handled as a new session and cannot make the connection to the original request/confirmation code.