Sample App is nonfunctional for core common use cases and actively misleads users, seems abandoned.
See original GitHub issueDescription
While attempting to integrate cognito into a project for work I have been hitting my head against a lot of issues. Its been really painful, and attempts to get support from amazon directly on use cases that seem very core to the product have only resulted in a lot of unhelpful fawning and apologies for known issues in cognito they admit to existing, yet refuse to fix, as well as promises that I would be updated with fixes that have since never happened despite waiting weeks and reporting the same issues working with different organizations multiple times over the past year or so, yet seeing them all be ignored despite support tickets, all with responses back that claim to value the feedback but actively do not provide solutions or fixes even after months of waiting.
This bug is a sincere attempt to get past my perceived malicious apathy of amazon customer service, and document a lot of these issues for the dev community, so I can then link to it in my support tickets and give that team an opportunity to show they are as customer focused as they claim, because nothing else has worked despite my multiple attempts to work with amazon in good faith.
It really doesn’t help that the sample project is so minimal and actively misleading; in many cases it provides incorrect guidance, leverages bad practices, or uses methods known by the community to not function as expected based on bug reports that were opened in good faith, then closed before a publicly available resolution for “inactivity”, which seems to be a overly common justification used to close tickets and not resolve them with solutions that a better working sample could just mitigate. Yet the same issues keep popping up, and we ourselves have run into a number of them.
Reproduction Steps
The sample app does not provide:
- A working JWT Token Auth access keys or refresh token -> access token user cases key to most apps who use it for mobile that shows how to provide/consume access token and refresh token JWT’s via Cognito. #99 as even though user.SessionTokens exists after a login, you have to first get the cognito user object and then pass that user object into the SignInManager.PasswordSignInAsync(user, …) overload and not the standard “username and password” overload for it to work, otherwise you just get nulls.
- A working expired access_token challenge that allows a refresh token to collect a new access token with only the refresh token (per the spec, the refresh token should be everything you need to get this, but the demo shows you need to log in a user, and for that you kneed to know more than just a refresh token can give you, so this conflicts with the standard and would not pass an overly strict security audit that only the refresh key be used.). A refresh token request requires an unauthenticated user because of the recursive tendencies around having an expired access key, so its important that this refresh be fully supported by default as a core part of the ciA of security is ACCESS. #150 #76 #149 #56
- A working “resend me a new confirmation code” flow. Bug #40 and #53 show some issues people have had since the current samples are not very instructional and actively mislead people on this path. The correct path seems to be to Use _signInManager.SignInAsync to sign in the by default anonymous user (?!) and then call CognitoUserManager<CognitoUser>.ResendSignupConfirmationCodeAsync(user) and not the standard userManager.SendEmailConfirmationTokenAsync(<CognitoUser>) as they are different flows to cognito even though to a user its the same “send me a token, I use it to validate” flow, but this also requires they be signed in and that’s not possible with unconfirmed accounts or users who did not get the initial confirmation code or who let it expire or had it forced to be expired when they got it due to the bad use of DateTime.Now instead of DateTime.UtcNow in the code per other bugs “closed for inactivity” that still exist; in fact the standard endpoint to reset a confirmation code so people can actually log in HAS to be
AllowAnonymous
so such users can become active users who can be logged in, so needing to log them in first can be risky if not impossible in some very standard scenarios since a non-validated user can’t. - A working account password change flow that uses the standard interfaces and no SOLID violating upcasting like in https://github.com/aws/aws-aspnet-cognito-identity-provider/blob/86761aba5e389dc416054ac4d682d7120f6f6ee8/samples/Samples/Areas/Identity/Pages/Account/ConfirmAccount.cshtml.cs#L22 and if you have a unconfirmed account per #44 there are gaps and the sample app doesn’t provide a path forward for all of these scenarios.
- A working initial account validate account flow that respects the dotnetcore interfaces or allows you to resend an auth validation token per the above. You currently cannot use the sample with standard objects to do this in our tests. Instead you have to down-cast (?!) the standard IUserManager interface into an amazon specific concrete CognitoUserManager<CognitoUser> per above and then use the resulting ConfirmForgotPassword method that is not supported by default on the standard interface, to send a confirmation token so a user can validate their account, because the one in the sample only throws an exception when used; this violates SOLID and other best practices, and is not even in the sample app unless you look very closely at the casting, so many people get stuck on account validation because the provider markets itself as being something that “just works”.
- A functional account recover user flow. The one used in the sample app uses the wrong object and method call and so it always fails in our tests; to get this working we had to instead use IAmazonCognitoIdentityProvider.ForgotPasswordAsync and leverage validated account recovery even though the sample app uses CognitoUserManager<CognitoUser>.ConfirmSignUpAsync(user, Input.Code, true); which is actively misleading.
- A working forgot password page and forgot password confirmation page per #171 #175 as the one at https://github.com/aws/aws-aspnet-cognito-identity-provider/blob/86761aba5e389dc416054ac4d682d7120f6f6ee8/samples/Samples/Areas/Identity/Pages/Account/ResetPassword.cshtml.cs#L75 also uses non-standard interfaces but doesn’t provide most of the needed functionality.
- A working example that shows the user of [Authorize(Roles= “{Role}”)] leveraging Congito Groups and the ‘cognito:groups’ field translation to Role claims via the standard Identity IClaimsTransformation injection #86
Other issues:
- You have to log in users unreasonably for otherwise simple operations and this is not reflected in the exceptions and errors.
- When JWT’s are enabled accessToken that’s generated by cognito doesn’t include an aud/audience field, so strict validation must be turned off.
- Every use of DateTime.Now instead of DateTime.UtcNow is a defect that breaks international teams and further complicates things.
Logs
See this github repo.
Environment
All.
Resolution
- 👋 Provide working examples for common user flows so users can trust that they are actually supported and working, instead of guessing and fighting for a week trying to google/stackoverflow/search bugs here to get enough data to find the right information. A lot of this is so core to the service offering that I would expect it to “just work” out of the box but that is not the case in my experience.
This is a 🐛 bug-report
Issue Analytics
- State:
- Created 2 years ago
- Reactions:5
- Comments:6 (1 by maintainers)
Just want to point out that as of right now, out of all the AWS services we consume, Cognito is the one that gives me the most fear and loathing.
And its not that Cognito is difficult to understand; Its just built wrong, by people who clearly don’t understand security or care about the mission they have been handed, as they seem to go out of the way to violate known RFC’s and standards out of what I can only assume is apathetic ignorance of what security and the security triad actually is because its not like this data doesn’t exist, its not like we are not telling them “Hey this is wrong, this is why its wrong, this is the spec you are violating, here is the line in the spec you are violating” and it still does not get fixed.
Add in the fact that the poor SDK team is stuck being the meatshield for the lazy Cognito team, a cognito development team who doesn’t want to fix issues the community reports are critical as otherwise our feedback would be welcomed, and you end up with a service that you cant trust… because that cognito service team does everything it can to not be customer focused.
The Cognito Service Team makes me trust Amazon/AWS Less. Things like this are just part of it; The security theater and refusal to fix known security issues is another part of it.
I cant agree more. .NET support in AWS in general is clearly lacking behind. Cognito is one of those areas.