Using standard API request in Firebase app check

182 views Asked by At

Recently google has introduced Standard API as a part of play integrity SDK.So now we have an option to choose between the previous implementation ie classic request and Standard API.

However, I am using FirebaseApp check which is a wrapper on top of the play integrity. The version that I am using is 17.1.1.Since Standard API is fairly new and still in beta it is not available in the Firebase app check. However, i wanted to try out it using Firebase, for that i created my own custom provider with the following implementation.I followed the same structure as the firebase and just in the place were Classic Provider was used, I used Standard Provider to generate the token.

StandardIntegrityAppCheckProviderFactory.kt

import com.google.firebase.FirebaseApp
import com.google.firebase.appcheck.AppCheckProvider
import com.google.firebase.appcheck.AppCheckProviderFactory

class StandardAppCheckProviderFactory :
    AppCheckProviderFactory {
    override fun create(firebaseApp: FirebaseApp): AppCheckProvider {
        return StandardIntegrityAppCheckProvider(firebaseApp)
    }
}

StandardIntegrityAppCheckProvider


class StandardIntegrityAppCheckProvider constructor(
    private val firebaseApp: FirebaseApp
) : AppCheckProvider {

    private val standardIntegrityManager by lazy {
        IntegrityManagerFactory.createStandard(firebaseApp.applicationContext)
    }
    private val networkClient by lazy {
        NetworkClient(firebaseApp)
    }

    private var integrityTokenProvider: StandardIntegrityTokenProvider? = null

    init {
        standardIntegrityManager.prepareIntegrityToken(
            PrepareIntegrityTokenRequest.builder()
                .setCloudProjectNumber(firebaseApp.options.gcmSenderId?.toLong() ?: 0).build()
        ).addOnSuccessListener {
            integrityTokenProvider = it
        }.addOnFailureListener {
            Log.e("StandardIntegrity", "exception = ${it.stackTrace}")
        }
    }

    override fun getToken(): Task<AppCheckToken> {
        return getPlayIntegrityAttestation()?.onSuccessTask { response ->
                val jsonObject = JSONObject()
                jsonObject.put("playIntegrityToken", response.token())
                Tasks.call(Executors.newSingleThreadScheduledExecutor()) {
                    networkClient.exchangeAttestationForAppCheckToken(
                        jsonObject.toString().toByteArray(UTF_8),
                        NetworkClient.PLAY_INTEGRITY,
                        RetryManager()
                    )
                }
            }?.continueWithTask {
               Tasks.forResult(
                    DefaultAppCheckToken.constructFromAppCheckTokenResponse(
                        it.result
                    )
                )
            }!!
    }

    private fun getPlayIntegrityAttestation(): Task<StandardIntegrityManager.StandardIntegrityToken> {
        return Tasks.call(
            Executors.newSingleThreadScheduledExecutor()
        ) {
            val jsonStr = networkClient.generatePlayIntegrityChallenge(
                JSONObject().toString().toByteArray(UTF_8), RetryManager()
            )
            val json = JSONObject(jsonStr)
            val challenge = json.optString("challenge")
            challenge
        }.onSuccessTask<StandardIntegrityManager.StandardIntegrityToken> { challenge ->
                integrityTokenProvider?.request(
                    StandardIntegrityTokenRequest.builder().setRequestHash(challenge).build()
                )!!
            }
    }
}

Now the token was generated via the provider successfully but the issue comes when i try to exchange the token for exchangeAttestationForAppCheckToken. exchangeAttestationForAppCheckToken is an API call to the firebase app check to provide exchangePlay integrity token that can be sent to the server. I am getting a 403 permission denied error whenever i use standard method. However if i use the classic method i am able to exchange the token successfully.

I have double checked every permission and API access to both Firebase app check API and play integrity API. All permissions are given. That is why it is working for classic, however for standard somehow it is giving a 403 error.

0

There are 0 answers