Android 15에서 인증 관리자는 사용자 인증 정보 생성 및 검색을 위한 원탭 흐름을 지원합니다. 이 흐름에서는 생성 중인 사용자 인증 정보 또는 사용 중인 사용자 인증 정보의 정보가 생체 인식 메시지에 더 많은 옵션의 진입점과 함께 직접 표시됩니다. 이 간소화된 프로세스를 통해 사용자 인증 정보 생성 및 검색 프로세스가 더 효율적이고 간소화됩니다.
요구사항:
- 사용자의 기기에 생체 인식이 설정되어 있고 사용자가 애플리케이션에 대한 인증을 위해 생체 인식을 허용합니다.
- 로그인 흐름의 경우 이 기능은 해당 계정에 여러 사용자 인증 정보 (예: 패스키 및 비밀번호)가 있는 경우에도 단일 계정 시나리오에만 사용 설정됩니다.
패스키 생성 흐름에서 한 번 탭하여 사용 설정
이 메서드의 생성 단계는 기존 사용자 인증 정보 생성 프로세스와 일치합니다. 패스키에 관한 요청인 경우 BeginCreatePublicKeyCredentialRequest
내에서 handleCreatePasskeyQuery()
를 사용하여 요청을 처리합니다.
is BeginCreatePublicKeyCredentialRequest -> {
Log.i(TAG, "Request is passkey type")
return handleCreatePasskeyQuery(request, passwordCount, passkeyCount)
}
handleCreatePasskeyQuery()
에서 CreateEntry
클래스와 함께 BiometricPromptData
를 포함합니다.
val createEntry = CreateEntry(
// Additional properties...
biometricPromptData = BiometricPromptData(
allowedAuthenticators = allowedAuthenticator
)
)
사용자 인증 정보 제공업체는 BiometricPromptData
인스턴스에서 allowedAuthenticator
속성을 명시적으로 설정해야 합니다. 이 속성을 설정하지 않으면 기본값은 DEVICE_WEAK
입니다. 사용 사례에 필요한 경우 선택사항인 cryptoObject
속성을 설정합니다.
로그인 패스키 흐름에서 원탭 사용 설정
패스키 생성 흐름과 마찬가지로 사용자 로그인 처리를 위한 기존 설정을 따릅니다. BeginGetPublicKeyCredentialOption
에서 populatePasskeyData()
를 사용하여 인증 요청과 관련된 정보를 수집합니다.
is BeginGetPublicKeyCredentialOption -> {
// ... other logic
populatePasskeyData(
origin,
option,
responseBuilder,
autoSelectEnabled,
allowedAuthenticator
)
// ... other logic as needed
}
CreateEntry
와 마찬가지로 BiometricPromptData
인스턴스는 PublicKeyCredentialEntry
인스턴스로 설정됩니다. allowedAuthenticator
를 명시적으로 설정하지 않으면 기본값은 BIOMETRIC_WEAK
입니다.
PublicKeyCredentialEntry(
// other properties...
biometricPromptData = BiometricPromptData(
allowedAuthenticators = allowedAuthenticator
)
)
사용자 인증 정보 항목 선택 처리
패스키 생성 또는 로그인 중 패스키 선택에 대한 사용자 인증 정보 항목 선택을 처리하는 동안 적절하게 PendingIntentHandler's
retrieveProviderCreateCredentialRequest
또는 retrieveProviderGetCredentialRequest
를 호출합니다. 이러한 객체는 제공자에게 필요한 메타데이터가 포함된 객체를 반환합니다. 예를 들어 패스키 생성 항목 선택을 처리할 때 다음과 같이 코드를 업데이트합니다.
val createRequest = PendingIntentHandler.retrieveProviderCreateCredentialRequest(intent)
if (createRequest == null) {
Log.i(TAG, "request is null")
setUpFailureResponseAndFinish("Unable to extract request from intent")
return
}
// Other logic...
val biometricPromptResult = createRequest.biometricPromptResult
// Add your logic based on what needs to be done
// after getting biometrics
if (createRequest.callingRequest is CreatePublicKeyCredentialRequest) {
val publicKeyRequest: CreatePublicKeyCredentialRequest =
createRequest.callingRequest as CreatePublicKeyCredentialRequest
if (biometricPromptResult == null) {
// Do your own authentication flow, if needed
}
else if (biometricPromptResult.isSuccessful) {
createPasskey(
publicKeyRequest.requestJson,
createRequest.callingAppInfo,
publicKeyRequest.clientDataHash,
accountId
)
} else {
val error = biometricPromptResult.authenitcationError
// Process the error
}
// Other logic...
}
이 예에는 생체 인식 흐름의 성공 여부에 관한 정보가 포함되어 있습니다. 사용자 인증 정보에 관한 기타 정보도 포함되어 있습니다. 흐름이 실패하면 biometricPromptResult.authenticationError
아래의 오류 코드를 사용하여 결정을 내립니다.
biometricPromptResult.authenticationError.errorCode
의 일부로 반환되는 오류 코드는 androidx.biometric 라이브러리에 정의된 오류 코드와 동일합니다(예: androidx.biometric.BiometricPrompt.NO_SPACE, androidx.biometric.BiometricPrompt.UNABLE_TO_PROCESS, androidx.biometric.BiometricPrompt.ERROR_TIMEOUT 등). authenticationError
에는 UI에 표시될 수 있는 errorCode
와 관련된 오류 메시지도 포함됩니다.
마찬가지로 retrieveProviderGetCredentialRequest
중에 메타데이터를 추출합니다.
생체 인식 흐름이 null
인지 확인합니다. 답이 '예'인 경우 자체 생체 인식을 구성하여 인증합니다. 이는 get 작업을 계측하는 방법과 비슷합니다.
val getRequest =
PendingIntentHandler.retrieveProviderGetCredentialRequest(intent)
if (getRequest == null) {
Log.i(TAG, "request is null")
setUpFailureResponseAndFinish("Unable to extract request from intent")
return
}
// Other logic...
val biometricPromptResult = getRequest.biometricPromptResult
// Add your logic based on what needs to be done
// after getting biometrics
if (biometricPromptResult == null)
{
// Do your own authentication flow, if necessary
} else if (biometricPromptResult.isSuccessful) {
Log.i(TAG, "The response from the biometricPromptResult was ${biometricPromptResult.authenticationResult.authenticationType}")
validatePasskey(
publicKeyRequest.requestJson,
origin,
packageName,
uid,
passkey.username,
credId,
privateKey
)
} else {
val error = biometricPromptResult.authenitcationError
// Process the error
}
// Other logic...