Credential Manager; geçiş anahtarları, birleşik oturum açma ve üçüncü taraf kimlik doğrulama sağlayıcıları desteğiyle Android'de kimlik doğrulama için önerilen API'dir. Kullanıcılara kimlik bilgilerini senkronize etme ve yönetme olanağı tanıyan güvenli ve kullanışlı bir ortam sunar. Yerel FIDO2 kimlik bilgilerini kullanan geliştiriciler, Credential Manager API ile entegrasyon yaparak uygulamalarını geçiş anahtarı kimlik doğrulamasını destekleyecek şekilde güncellemeli. Bu belgede, projenizi FIDO2'den Kimlik Bilgisi Yöneticisi'ne nasıl taşıyacağınız açıklanmaktadır.
FIDO2'den Kimlik Bilgisi Yöneticisi'ne geçiş yapma nedenleri
Çoğu durumda, Android uygulamanızın kimlik doğrulama sağlayıcısını Kimlik Bilgisi Yöneticisi'ne taşımanız gerekir. Kimlik bilgisi yöneticisine geçiş yapmanın nedenleri şunlardır:
- Geçiş anahtarı desteği: Kimlik Bilgisi Yöneticisi, şifrelerden daha güvenli ve kullanımı daha kolay olan yeni bir şifresiz kimlik doğrulama mekanizması olan geçiş anahtarlarını destekler.
- Birden fazla oturum açma yöntemi: Kimlik Bilgisi Yöneticisi; şifreler, geçiş anahtarları ve federasyon oturum açma yöntemleri dahil olmak üzere birden fazla oturum açma yöntemini destekler. Bu sayede, tercih ettikleri kimlik doğrulama yönteminden bağımsız olarak kullanıcıların uygulamanızda kimlik doğrulaması yapması kolaylaşır.
- Üçüncü taraf kimlik bilgisi sağlayıcı desteği: Android 14 ve sonraki sürümlerde, Kimlik Bilgisi Yöneticisi birden fazla üçüncü taraf kimlik bilgisi sağlayıcıyı destekler. Bu, kullanıcılarınızın uygulamanızda oturum açmak için diğer sağlayıcılardan aldıkları mevcut kimlik bilgilerini kullanabileceği anlamına gelir.
- Tutarlı kullanıcı deneyimi: Kimlik Bilgisi Yöneticisi, uygulamalarda kimlik doğrulama ve oturum açma mekanizmalarında daha tutarlı bir kullanıcı deneyimi sağlar. Bu sayede kullanıcılar, uygulamanızın kimlik doğrulama akışını daha kolay anlayıp kullanabilir.
FIDO2'den Kimlik Bilgisi Yöneticisi'ne geçişi başlatmak için aşağıdaki adımları uygulayın.
Bağımlılıkları güncelleme
Projenizin build.gradle dosyasındaki Kotlin eklentisini 1.8.10 veya daha yüksek bir sürüme güncelleyin.
plugins { //… id 'org.jetbrains.kotlin.android' version '1.8.10' apply false //… }
Projenizin
build.gradle
bölümünde, bağımlılıklarınızı güncelleyerek Kimlik Bilgisi Yöneticisi ve Play Hizmetleri Kimlik Doğrulama kitaplıklarının en yeni sürümlerini kullanın.dependencies { // ... // Credential Manager: implementation 'androidx.credentials:credentials:<latest-version>' // Play Services Authentication: // Optional - needed for credentials support from play services, for devices running // Android 13 and below: implementation 'androidx.credentials:credentials-play-services-auth:<latest-version>' // ... }
FIDO başlatmayı, Kimlik Bilgisi Yöneticisi başlatmayla değiştirin. Geçiş anahtarı oluşturma ve oturum açma yöntemleri için kullandığınız sınıfa şu bildirimi ekleyin:
val credMan = CredentialManager.create(context)
Geçiş anahtarı oluşturma
Kullanıcının geçiş anahtarıyla oturum açabilmesi için yeni bir geçiş anahtarı oluşturmanız, bunu kullanıcının hesabıyla ilişkilendirmeniz ve geçiş anahtarının herkese açık anahtarını sunucunuzda saklamanız gerekir. Kayıt işlevi çağrılarını güncelleyerek uygulamanızı bu özelliğe göre ayarlayın.
Geçiş anahtarı oluşturma sırasında
createCredential()
yöntemine gönderilen gerekli parametreleri almak içinname("residentKey").value("required")
(WebAuthn spesifikasyonunda açıklandığı gibi)registerRequest()
sunucu çağrınıza ekleyin.suspend fun registerRequest() { // ... val call = client.newCall( Builder() .method("POST", jsonRequestBody { name("attestation").value("none") name("authenticatorSelection").objectValue { name("residentKey").value("required") } }).build() ) // ... }
registerRequest()
ve tüm alt işlevler içinreturn
türünüJSONObject
olarak ayarlayın.suspend fun registerRequest(sessionId: String): ApiResult<JSONObject> { val call = client.newCall( Builder() .url("$BASE_URL/<your api url>") .addHeader("Cookie", formatCookie(sessionId)) .method("POST", jsonRequestBody { name("attestation").value("none") name("authenticatorSelection").objectValue { name("authenticatorAttachment").value("platform") name("userVerification").value("required") name("residentKey").value("required") } }).build() ) val response = call.await() return response.result("Error calling the api") { parsePublicKeyCredentialCreationOptions( body ?: throw ApiException("Empty response from the api call") ) } }
Görünümünüzden, amaç başlatıcı ve etkinlik sonucu çağrılarını işleyen tüm yöntemleri güvenli bir şekilde kaldırın.
registerRequest()
artıkJSONObject
döndürdüğündenPendingIntent
oluşturmanız gerekmez. Döndürülen amacıJSONObject
ile değiştirin. Niyet başlatıcı çağrılarınızı, Credential Manager API'dencreateCredential()
çağıracak şekilde güncelleyin.createCredential()
API yöntemini çağırın.suspend fun createPasskey( activity: Activity, requestResult: JSONObject ): CreatePublicKeyCredentialResponse? { val request = CreatePublicKeyCredentialRequest(requestResult.toString()) var response: CreatePublicKeyCredentialResponse? = null try { response = credMan.createCredential( request = request as CreateCredentialRequest, context = activity ) as CreatePublicKeyCredentialResponse } catch (e: CreateCredentialException) { showErrorAlert(activity, e) return null } return response }
Arama başarılı olduktan sonra yanıtı sunucuya geri gönderin. Bu arama için istek ve yanıt, FIDO2 uygulamasına benzer olduğundan herhangi bir değişiklik yapılması gerekmez.
Geçiş anahtarlarıyla kimlik doğrulama
Geçiş anahtarı oluşturmayı ayarladıktan sonra, uygulamanızı kullanıcıların geçiş anahtarlarını kullanarak oturum açmasına ve kimlik doğrulamasına izin verecek şekilde ayarlayabilirsiniz. Bunu yapmak için kimlik doğrulama kodunuzu, Kimlik Bilgisi Yöneticisi sonuçlarını işleyecek şekilde güncelleyip geçiş anahtarlarıyla kimlik doğrulama işlevi uygulayacaksınız.
getCredential()
isteğine gönderilecek gerekli bilgileri almak için sunucuya yaptığınız oturum açma isteği çağrısı, FIDO2 uygulamasıyla aynıdır. Herhangi bir değişiklik yapılması gerekmez.Kayıt isteği çağrısına benzer şekilde, döndürülen yanıt JSONObject biçimindedir.
/** * @param sessionId The session ID to be used for the sign-in. * @param credentialId The credential ID of this device. * @return a JSON object. */ suspend fun signinRequest(): ApiResult<JSONObject> { val call = client.newCall(Builder().url(buildString { append("$BASE_URL/signinRequest") }).method("POST", jsonRequestBody {}) .build() ) val response = call.await() return response.result("Error calling /signinRequest") { parsePublicKeyCredentialRequestOptions( body ?: throw ApiException("Empty response from /signinRequest") ) } } /** * @param sessionId The session ID to be used for the sign-in. * @param response The JSONObject for signInResponse. * @param credentialId id/rawId. * @return A list of all the credentials registered on the server, * including the newly-registered one. */ suspend fun signinResponse( sessionId: String, response: JSONObject, credentialId: String ): ApiResult<Unit> { val call = client.newCall( Builder().url("$BASE_URL/signinResponse") .addHeader("Cookie",formatCookie(sessionId)) .method("POST", jsonRequestBody { name("id").value(credentialId) name("type").value(PUBLIC_KEY.toString()) name("rawId").value(credentialId) name("response").objectValue { name("clientDataJSON").value( response.getString("clientDataJSON") ) name("authenticatorData").value( response.getString("authenticatorData") ) name("signature").value( response.getString("signature") ) name("userHandle").value( response.getString("userHandle") ) } }).build() ) val apiResponse = call.await() return apiResponse.result("Error calling /signingResponse") { } }
Niyet başlatıcıyı ve etkinlik sonucu çağrılarını işleyen tüm yöntemleri görünümünüzden güvenli bir şekilde kaldırın.
signInRequest()
artıkJSONObject
döndürdüğündenPendingIntent
oluşturmanız gerekmez. Döndürülen amacıJSONObject
ile değiştirin ve API yöntemlerinizdengetCredential()
işlevini çağırın.suspend fun getPasskey( activity: Activity, creationResult: JSONObject ): GetCredentialResponse? { Toast.makeText( activity, "Fetching previously stored credentials", Toast.LENGTH_SHORT) .show() var result: GetCredentialResponse? = null try { val request= GetCredentialRequest( listOf( GetPublicKeyCredentialOption( creationResult.toString(), null ), GetPasswordOption() ) ) result = credMan.getCredential(activity, request) if (result.credential is PublicKeyCredential) { val publicKeycredential = result.credential as PublicKeyCredential Log.i("TAG", "Passkey ${publicKeycredential.authenticationResponseJson}") return result } } catch (e: Exception) { showErrorAlert(activity, e) } return result }
Çağrı başarılı olduktan sonra yanıtı sunucuya geri göndererek kullanıcıyı doğrulayın ve kimliğini onaylayın. Bu API çağrısının istek ve yanıt parametreleri, FIDO2 uygulamasına benzer olduğundan herhangi bir değişiklik yapılması gerekmez.
Ek kaynaklar
- Kimlik Bilgisi Yöneticisi örnek referansı
- Kimlik Bilgisi Yöneticisi Codelab'i
- Credential Manager API'yi kullanarak geçiş anahtarlarıyla uygulamalarınıza sorunsuz kimlik doğrulama ekleme
- FIDO2 codelab'i