TouchID для аутентификации системного пароля
Я хочу использовать TouchID для аутентификации моего собственного приложения.
1. Я хочу, чтобы пользователь мог нажать "Ввести код доступа", чтобы вызывать экран с кодом доступа к системе, чтобы пройти аутентификацию, если успех затем входит в мое собственное приложение.
Но я не знаю, как это сделать, чтобы передать код проверки подлинности с паролем, например, следующий экран в случае 'LAErrorUserFallback'
![enter image description here]()
Вот мой код:
LAContext *context = [[LAContext alloc] init];
__block NSString *msg;
__block BOOL bAuth;
// show the authentication UI with our reason string
[context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:NSLocalizedString(@"Unlock APP With FingerPrint", nil) reply:
^(BOOL success, NSError *authenticationError) {
if (success) {
bAuth = YES;
msg =[NSString stringWithFormat:NSLocalizedString(@"EVALUATE_POLICY_SUCCESS", nil)];
dispatch_async(dispatch_get_main_queue(), ^{
[[MYAppDelegate theDelegate] initializeAppAfterKeyVaultUnlocked];
});
NSLog(@"%@",msg);
} else {
bAuth = NO;
switch (authenticationError.code) {
case LAErrorAuthenticationFailed:
msg = [NSString stringWithFormat:NSLocalizedString(@"Authentication Failed", nil)];
// ...
break;
case LAErrorUserCancel:
msg = [NSString stringWithFormat:NSLocalizedString(@"User pressed Cancel button", nil)];
dispatch_async(dispatch_get_main_queue(), ^{
[[MYAppDelegate theDelegate] exitAndLock];
});
break;
case LAErrorUserFallback:
msg = [NSString stringWithFormat:NSLocalizedString(@"User pressed \"Enter Password\"", nil)];
//Here I want to fallback to iOS build-in passcode authenticate view, and get the auth result.
break;
default:
msg = [NSString stringWithFormat:NSLocalizedString(@"Touch ID is not configured", nil)];
// ...
break;
}
NSLog(@"%@",authenticationError.localizedDescription);
}
}];
Ответы
Ответ 1
Теперь в iOS 9 это довольно просто: вам просто нужно использовать LAPolicyDeviceOwnerAuthentication
вместо LAPolicyDeviceOwnerAuthenticationWithBiometrics
Итак, в вашем коде вы просто замените это:
[context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:NSLocalizedString(@"Unlock APP With FingerPrint", nil) reply:
^(BOOL success, NSError *authenticationError) {
При этом:
[context evaluatePolicy:LAPolicyDeviceOwnerAuthentication localizedReason:NSLocalizedString(@"Unlock APP With FingerPrint", nil) reply:
^(BOOL success, NSError *authenticationError) {
Таким образом, когда пользователь не может выполнить аутентификацию с помощью отпечатка пальца, будет включен параметр "ввести пароль", который будет вызывать экран ввода кода системного пароля.
Ответ 2
В моем понимании вам нужно будет самостоятельно создать экран кода доступа, если вы хотите использовать функцию оценкиPolicy.
Если вы используете keychain, функция SecItemCopyMatching автоматически возвращается к коду доступа, если аппликатура терпит неудачу. Вот ссылка о том, как это сделать (см. Раздел 3): https://www.secsign.com/fingerprint-validation-as-an-alternative-to-passcodes/
Ответ 3
Не пробовал, но это сообщение требует, что вы можете использовать систему, следуя здесь (Это работает только с iOS 8 или новее).
Или (это то, что я сделал) вы можете создать свой экран ввода пароля (для поддержки более старых версий iOS), мой контроллер имеет представление ввода кода доступа, которое будет отображаться, когда пользователь выбирает использовать пароль. В этот момент вызов назад из метода оценкиPolicy вернется с помощью LAErrorUserFallback, который может быть временем для открытия вашего пользовательского экрана кода доступа.
что-то вроде этого:
-(void)maybeShowTouchIDMessage {
if (![SettingsManager sharedManager].isUseTouchID || self.createPassCodeMode) {
self.shieldView.hidden = YES;
return;
}
self.shieldView.hidden = NO;
self.shieldView.alpha = 1.0;
LAContext *context = [[LAContext alloc] init];
NSError *evalError = nil;
if ([context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&evalError] ) {
__weak SecurityWindowViewController *weakSelf = self;
[context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
localizedReason:@"Use touch id \n or hit \"Cancel\" to enter passcode"
reply:^(BOOL success, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
SecurityWindowViewController *strongSelf = weakSelf;
if (success) {
[strongSelf hideWithSuccess:YES];
} else if (error){
NSString *errorMessage;
BOOL showError = NO;
switch (error.code) {
case LAErrorAuthenticationFailed:
errorMessage = @"Sorry couldn't autheticate";
showError = YES;
break;
case LAErrorPasscodeNotSet:
errorMessage = @"Sorry couldn't autheticate";
showError = YES;
break;
case LAErrorTouchIDNotEnrolled:
errorMessage = @"Touch ID has no enrolled fingers";
showError = YES;
break;
default:
showError = NO;
break;
}
[UIView animateWithDuration:0.5 animations:^{
strongSelf.shieldView.alpha = 0.0;
} completion:^(BOOL finished) {
strongSelf.shieldView.hidden = YES;
}];
if (showError) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error"
message:errorMessage
delegate:nil
cancelButtonTitle:@"Ok"
otherButtonTitles:nil];
[alert show];
}
}
});
}];
}
Ответ 4
Вы можете добавить еще один случай и вызвать экран своего пароля.
Вот мой код:
LAContext *myContext = [[LAContext alloc] init];
NSError *authError = nil;
NSString *myLocalizedReasonString = strMessage;
objFlockr.pVerificationBlock = objResponse;
if ([myContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&authError]) {
if (!isShow) {
myContext.localizedFallbackTitle = @"";
}
else
{
myContext.localizedFallbackTitle = @"Set Up Passcode";
}
[myContext evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
localizedReason:myLocalizedReasonString
reply:^(BOOL succes, NSError *error) {
if (!AppDel.firstAttampt && succes && !isShow)
{
if (objFlockr.pVerificationBlock)
objFlockr.pVerificationBlock(1);
}
else if (succes) {
if (objFlockr.pVerificationBlock)
objFlockr.pVerificationBlock(0);
NSLog(@"User authenticated");
} else {
switch (error.code) {
case LAErrorAuthenticationFailed:
NSLog(@"Authentication Failed");
if (objFlockr.pVerificationBlock)
objFlockr.pVerificationBlock(1);
break;
case LAErrorUserCancel:
NSLog(@"User pressed Cancel button");
if (objFlockr.pVerificationBlock)
objFlockr.pVerificationBlock(3);
break;
case LAErrorUserFallback:
NSLog(@"User pressed \"Enter Password\"");
if (objFlockr.pVerificationBlock)
objFlockr.pVerificationBlock(4);
break;
default:
[self showMessage:@"Touch ID is not configured" withTitle:@"Error"];
if (objFlockr.pVerificationBlock)
objFlockr.pVerificationBlock(2);
NSLog(@"Touch ID is not configured");
break;
}
NSLog(@"Authentication Fails");
}
}];
} else {
NSLog(@"Can not evaluate Touch ID");
[self showMessage:@"Can not evaluate TouchID" withTitle:@"Error"];
}