aws-amplify / amplify-flutter

A declarative library with an easy-to-use interface for building Flutter applications on AWS.
https://docs.amplify.aws
Apache License 2.0
1.31k stars 243 forks source link

Sign in using biometrics #2938

Open bjernie opened 1 year ago

bjernie commented 1 year ago

Description

What is the best practice for using Amplify in conjunction with biometrics to sign a user in?

I feel like storing the username and password as plain text behind local_auth and flutter_secure_storage is a bad practice, but I don't know what the best practice is when Amplify is involved.

Have anyone else solved this?

Categories

Steps to Reproduce

No response

Screenshots

No response

Platforms

Flutter Version

3.7.12

Amplify Flutter Version

1.0.0

Deployment Method

Custom Pipeline

Schema

No response

dnys1 commented 1 year ago

So, my understanding of biometric authentication is that it's used to supplement existing authentication schemes, not replace them entirely. For example, if a user has never signed into a device, simple biometric auth would not be sufficient to validate their identity and log them in. However, once a user signed in then biometric auth could be used to gate session refreshes, allowing the user to stay logged in on subsequent app openings without reauthenticating with username/password.

This is how I've seen many apps do it. On the login page, they'll have an Enable Face ID toggle which, when checked, will enable Face ID for all subsequent app opens. In an Amplify Flutter app, this would be handled outside of Amplify. Anytime the app opened, your loading screen would use the local_auth package to verify biometric identity. If it succeeds, then continue to the app and if not, then call Amplify.Auth.signOut to clear credentials from secure storage. But Amplify Flutter would consider the user logged in the entire time.

bjernie commented 1 year ago

@dnys1 Doesn't that introduce security issues when the user is still authenticated in the background when the app is reopened, doesn't that make Face ID "fake security"? You could technically still make requests as a signed in user even if you never get past Face ID.

It just seems like a rather large security hole

dnys1 commented 1 year ago

You can play with limiting keychain access based on Face ID/Touch ID: https://developer.apple.com/documentation/localauthentication/accessing_keychain_items_with_face_id_or_touch_id. This would mean that even though credentials were saved locally, they are not accessible until a successful Face ID is completed.

That being said, we don't have a way to configure this using Amplify Auth, but you can pass in any class which implements SecureStorageInterface which could interact with Keychain and set this restriction: https://docs.amplify.aws/lib/auth/managing_credentials/q/platform/flutter/

aardrop commented 1 year ago

@dnys1 Doesn't that introduce security issues when the user is still authenticated in the background when the app is reopened, doesn't that make Face ID "fake security"? You could technically still make requests as a signed-in user even if you never get past Face ID.

It just seems like a rather large security hole

As @dnys1 said, my understanding is that it's the same security practice that's used for key chains like the iOS password and username storage, just with face authentication as the barrier to use. I can't speak to this package specifically, but I believe that's the idea behind most device biometrics right now.

This reddit thread covers how we should probably be using a JWT to create or activate a session with the local storage but isn't possible with flutter amplify right now. https://www.reddit.com/r/flutterhelp/comments/12ze5j2/use_biometrics_in_conjunction_with_aws_amplify_to/