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.authenticationError
// Process the error
}
// Other logic...
}
이 예시에는 생체 인식 흐름의 성공에 관한 정보가 포함되어 있습니다. 또한 사용자 인증 정보에 관한 기타 정보도 포함되어 있습니다. 흐름이 실패하면 biometricPromptResult.authenticationError
아래의 오류 코드를 사용하여 결정을 내립니다.
biometricPromptResult.authenticationError.errorCode
의 일부로 반환되는 오류 코드는 androidx.biometric.BiometricPrompt.NO_SPACE, androidx.biometric.BiometricPrompt.UNABLE_TO_PROCESS, androidx.biometric.BiometricPrompt.ERROR_TIMEOUT 등 androidx.biometric 라이브러리에 정의된 오류 코드와 동일합니다. authenticationError
에는 UI에 표시할 수 있는 errorCode
와 연결된 오류 메시지도 포함됩니다.
마찬가지로 retrieveProviderGetCredentialRequest
중에 메타데이터를 추출합니다.
생체 인식 흐름이 null
인지 확인합니다. 예인 경우 인증을 위해 자체 생체 인식을 구성합니다. 이는 작업 가져오기가 계측되는 방식과 유사합니다.
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.authenticationError
// Process the error
}
// Other logic...