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

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