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...