Xamarin.iOS에서 터치 ID 및 얼굴 ID 사용
iOS는 두 가지 바이오 메트릭 인증 시스템을 지원합니다.
- 터치 ID 는 홈 단추 아래에 지문 센서를 사용합니다.
- 얼굴 ID 는 전면 카메라 센서를 사용하여 얼굴 스캔으로 사용자를 인증합니다.
터치 ID는 iOS 7 및 iOS 11의 Face ID에 도입되었습니다.
이러한 인증 시스템은 Secure Enclave라는 하드웨어 기반 보안 프로세서를 사용합니다. Secure Enclave는 얼굴 및 지문 데이터의 수학적 표현을 암호화하고 이 정보를 사용하여 사용자를 인증합니다. Apple에 따르면 얼굴 및 지문 데이터는 장치를 떠나지 않으며 iCloud에 백업되지 않습니다. 앱은 로컬 인증 API를 통해 Secure Enclave와 상호 작용하며 얼굴 또는 지문 데이터를 검색하거나 Secure Enclave에 직접 액세스할 수 없습니다.
보호된 콘텐츠에 대한 액세스를 제공하기 전에 앱에서 터치 ID 및 얼굴 ID를 사용하여 사용자를 인증할 수 있습니다.
로컬 인증 컨텍스트
iOS의 생체 인식 인증은 클래스의 인스턴스인 로컬 인증 컨텍스트 개체를 LAContext
사용합니다. 클래스를 LAContext
사용하면 다음을 수행할 수 있습니다.
- 바이오 메트릭 하드웨어의 가용성을 확인합니다.
- 인증 정책을 평가합니다.
- 액세스 제어를 평가합니다.
- 인증 프롬프트를 사용자 지정하고 표시합니다.
- 인증 상태를 다시 사용하거나 무효화합니다.
- 자격 증명을 관리합니다.
사용 가능한 인증 방법 검색
샘플 프로젝트에는 .에 AuthenticationView
의해 지원되는 항목이 AuthenticationViewController
포함됩니다. 이 클래스는 사용 가능한 인증 방법을 검색하도록 메서드를 재정의 ViewWillAppear
합니다.
partial class AuthenticationViewController: UIViewController
{
// ...
string BiometryType = "";
public override void ViewWillAppear(bool animated)
{
base.ViewWillAppear(animated);
unAuthenticatedLabel.Text = "";
var context = new LAContext();
var buttonText = "";
// Is login with biometrics possible?
if (context.CanEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, out var authError1))
{
// has Touch ID or Face ID
if (UIDevice.CurrentDevice.CheckSystemVersion(11, 0))
{
context.LocalizedReason = "Authorize for access to secrets"; // iOS 11
BiometryType = context.BiometryType == LABiometryType.TouchId ? "Touch ID" : "Face ID";
buttonText = $"Login with {BiometryType}";
}
// No FaceID before iOS 11
else
{
buttonText = $"Login with Touch ID";
}
}
// Is pin login possible?
else if (context.CanEvaluatePolicy(LAPolicy.DeviceOwnerAuthentication, out var authError2))
{
buttonText = $"Login"; // with device PIN
BiometryType = "Device PIN";
}
// Local authentication not possible
else
{
// Application might choose to implement a custom username/password
buttonText = "Use unsecured";
BiometryType = "none";
}
AuthenticateButton.SetTitle(buttonText, UIControlState.Normal);
}
}
이 ViewWillAppear
메서드는 UI가 사용자에게 표시하려고 할 때 호출됩니다. 이 메서드는 새 인스턴스를 LAContext
정의하고 이 메서드를 CanEvaluatePolicy
사용하여 바이오 메트릭 인증이 사용되는지 여부를 확인합니다. 그렇다면 시스템 버전과 BiometryType
열거형을 검사 사용할 수 있는 바이오 메트릭 옵션을 결정합니다.
바이오 메트릭 인증을 사용하지 않는 경우 앱은 PIN 인증으로 대체하려고 시도합니다. 바이오 메트릭 또는 PIN 인증을 사용할 수 없는 경우 디바이스 소유자는 보안 기능을 사용하도록 설정하지 않았으며 로컬 인증을 통해 콘텐츠를 보호 할 수 없습니다.
사용자 인증
샘플 프로젝트에는 AuthenticationViewController
사용자 인증을 AuthenticateMe
담당하는 메서드가 포함되어 있습니다.
partial class AuthenticationViewController: UIViewController
{
// ...
string BiometryType = "";
partial void AuthenticateMe(UIButton sender)
{
var context = new LAContext();
NSError AuthError;
var localizedReason = new NSString("To access secrets");
// Because LocalAuthentication APIs have been extended over time,
// you must check iOS version before setting some properties
context.LocalizedFallbackTitle = "Fallback";
if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0))
{
context.LocalizedCancelTitle = "Cancel";
}
if (UIDevice.CurrentDevice.CheckSystemVersion(11, 0))
{
context.LocalizedReason = "Authorize for access to secrets";
BiometryType = context.BiometryType == LABiometryType.TouchId ? "TouchID" : "FaceID";
}
// Check if biometric authentication is possible
if (context.CanEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, out AuthError))
{
replyHandler = new LAContextReplyHandler((success, error) =>
{
// This affects UI and must be run on the main thread
this.InvokeOnMainThread(() =>
{
if (success)
{
PerformSegue("AuthenticationSegue", this);
}
else
{
unAuthenticatedLabel.Text = $"{BiometryType} Authentication Failed";
}
});
});
context.EvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, localizedReason, replyHandler);
}
// Fall back to PIN authentication
else if (context.CanEvaluatePolicy(LAPolicy.DeviceOwnerAuthentication, out AuthError))
{
replyHandler = new LAContextReplyHandler((success, error) =>
{
// This affects UI and must be run on the main thread
this.InvokeOnMainThread(() =>
{
if (success)
{
PerformSegue("AuthenticationSegue", this);
}
else
{
unAuthenticatedLabel.Text = "Device PIN Authentication Failed";
AuthenticateButton.Hidden = true;
}
});
});
context.EvaluatePolicy(LAPolicy.DeviceOwnerAuthentication, localizedReason, replyHandler);
}
// User hasn't configured any authentication: show dialog with options
else
{
unAuthenticatedLabel.Text = "No device auth configured";
var okCancelAlertController = UIAlertController.Create("No authentication", "This device does't have authentication configured.", UIAlertControllerStyle.Alert);
okCancelAlertController.AddAction(UIAlertAction.Create("Use unsecured", UIAlertActionStyle.Default, alert => PerformSegue("AuthenticationSegue", this)));
okCancelAlertController.AddAction(UIAlertAction.Create("Cancel", UIAlertActionStyle.Cancel, alert => Console.WriteLine("Cancel was clicked")));
PresentViewController(okCancelAlertController, true, null);
}
}
}
로그인 AuthenticateMe
단추를 탭하는 사용자에 대한 응답으로 메서드가 호출됩니다. 새 LAContext
개체가 인스턴스화되고 디바이스 버전이 검사 로컬 인증 컨텍스트에서 설정할 속성을 결정합니다.
이 CanEvaluatePolicy
메서드는 바이오 메트릭 인증을 사용하는 경우 검사, 가능한 경우 PIN 인증으로 대체하고, 인증을 사용할 수 없는 경우 마지막으로 보안되지 않은 모드를 제공하기 위해 호출됩니다. 인증 방법을 사용할 수 있는 EvaluatePolicy
경우 이 메서드는 UI를 표시하고 인증 프로세스를 완료하는 데 사용됩니다.
샘플 프로젝트에는 인증에 성공하면 데이터를 표시하는 모의 데이터와 보기가 포함되어 있습니다.