Skip to content

Instantly share code, notes, and snippets.

@lbalmaceda
Created April 17, 2017 15:10
Show Gist options
  • Save lbalmaceda/66d731eddc537b6da38814b7e7a523c7 to your computer and use it in GitHub Desktop.
Save lbalmaceda/66d731eddc537b6da38814b7e7a523c7 to your computer and use it in GitHub Desktop.
Auth0 Fingerprint API

Auth0 Fingerprint API

Create a new instance

The context is needed to access the check for availability

public class Auth0Fingerprint implements FingerprintManager.AuthenticationCallback {

  private final FingerprintManagerCompat manager;

  public Auth0Fingerprint (Context context){
    //Use the support version as it handles the missing APIs case
    manager = new FingerprintManagerCompat(context);
  }
  
  //See below for the other methods
}

Helper to request/check for permission

public static boolean checkPermission(Context context) {
  int permissionCheck = ContextCompat.checkSelfPermission(context, Manifest.permission.USE_FINGERPRINT);
  return permissionCheck == PackageManager.PERMISSION_GRANTED;
}

public static void requestPermission(Activity activity, int requestCode) {
  if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.USE_FINGERPRINT)) {
    //Show explanation and retry.
    //AlertDialog ...
  } else {
    ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.USE_FINGERPRINT}, requestCode);
  }
}

Check for Sensor/ScreenLock/Fingerprints availability.

public boolean isAvailable() {
  if (!manager.isHardwareDetected()){
    throw new IllegalStateException("Fingerprint scanner not available.");
  }
  if (!manager.hasEnrolledFingerprints()){
    throw new IllegalStateException("No fingerprints enrolled.");
  }
 
  return manager.isHardwareDetected() && manager.hasEnrolledFingerprints();
}

Ask for authentication

public boolean authenticate() {
  return manager.authenticate(createCryptoObject(), new CancellationSignal(), this, null);
}
@nikolaseu
Copy link

hay mucha implementación acá :)

que significa boolean authenticate() ? que pasa si el usuario registra un nuevo dedo? sirve para realmente validar que el usuario es el que originalmente quiso proteger algo?

para mi todo esto debería usarse para "guardar algo secreto" (si despues no lo queres usar esta bien, no pasa nada).
entonces authenticate, si todo esta bien, te devuelve "ese secreto que guardaste".
y puede ser cancelado o directamente fallar cuando no esta disponible.

hace falta un método registerForAuthentication() o algo asi que es que inicializa. es como que el usuario dice:

A partir de ahora quiero que me pidas fingerprint. 
Esto es lo que quiero que guardes, asi despues puedo chequear que haya sido yo el mismo que lo desbloquea

@nikolaseu
Copy link

nikolaseu commented Apr 17, 2017

The general methods are ok (for handling permission, availability etc) but I propose something like this for authentication:

class FingerprintAuth {
    // constructor
    // label is optional and is used to match the register/authentication. may be overkill but you might use this lib to protect different places of the app
    public FingerprintAuth(Context context, String label) {
        // TODO
    }

    // register a key with the current user/fingerprints
    // secret: might be null, but will be sent on the authenticated callback when authentication succeeds
    // invalidatedByBiometricEnrollment: if false, the created key will not be invalidated even if a new fingerprint is enrolled
    public void register(String secret, boolean invalidatedByBiometricEnrollment) {
        // creates the fingerprint-protected key in the keystore, using the provided label (or a default if none was provided)
        // if not null, saves the secret somewhere using the created keystore key
    }

    public void authenticate(FingerPrintAuth.Callback callback) {
        // check if fingerprint-protected key exists/is available:
        //     --> if key is not available, call callback.onError() and exits
        //     --> if key is available, continue
        // asks for fingerprint
        //     --> on success: unlocks the key, use the key to decrypt the secret (if there was one) and calls callback.onAuthenticated() and exits
        // in any moment, if user cancels, calls callback.onCanceled() and exits
        // if initially there was a secret provided, in any moment the user is allowed to just input it manually
    }

    public interface Callback {
        void onAuthenticated(String secret); // secret might be null, but the callback includes it anyway
        void onCanceled(); // user cancelled
        void onError(Throwable error); // anything might fail but the most common use case for this callback will be when the user removed/changed the registered fingerprints and we cannot authenticate anyone anymore
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment