首页 > 解决方案 > 在 Java 中请求 ID 令牌

问题描述

我正在开发一个使用 Firebase 进行身份验证的 Spring Boot REST API(即,它使用 Admin SDK 来验证传递的 ID 令牌)。我使用没有自定义身份验证的标准 Firebase ID 令牌。

Spring AuthenticationProvider

@Component
class FirebaseAuthenticationProvider(private val firebaseAuth: FirebaseAuth) :
        AbstractUserDetailsAuthenticationProvider() {

    override fun supports(authentication: Class<*>?): Boolean {
        return FirebaseAuthenticationToken::class.java.isAssignableFrom(authentication)
    }

    override fun retrieveUser(username: String?, authentication: UsernamePasswordAuthenticationToken?): UserDetails {
        var firebaseAuthenticationToken = authentication as FirebaseAuthenticationToken

        val task = firebaseAuth.verifyIdTokenAsync(firebaseAuthenticationToken.token)

        try {
            val firebaseToken = task.get()
            return FirebaseUserDetails(firebaseToken.email, firebaseToken.uid)
        } catch (e: Exception) {
            when (e) {
                is InterruptedException, is ExecutionException -> {
                    throw SessionAuthenticationException(e.message)
                }
                else -> throw e
            }
        }

    }

    override fun additionalAuthenticationChecks(userDetails: UserDetails?,
                                                authentication: UsernamePasswordAuthenticationToken?) {
        // nothing to do here
    }

}

我想集成测试提取令牌并通过 Admin SDK 验证它的组件。为此,我想模拟一个 Android 客户端并在每次测试运行时为测试用户检索一个新的 ID 令牌。

例如

@Test
fun `accepts valid token`() {

    // HOW TO DO THIS       
    val testToken: String = ???????????

    println("Acquired token $testToken")

    mockMvc.perform(get("/").header(FirebaseAuthenticationTokenFilter.TOKEN_HEADER, testToken))
            .andExpect(status().isOk)   
}

给定正确的电子邮件和密码,如何在纯 Java 中检索有效的 ID 令牌?

我尝试使用 IdentityToolkit REST API

private fun getTokenForTestUser() : String {
    val restClient = RestTemplate()
    val json = JSONObject().put("email", testUsername).put("password", testPassword)
    val headers = HttpHeaders()
    headers.contentType = MediaType.APPLICATION_JSON
    headers.accept = listOf(MediaType.APPLICATION_JSON)
    val request = HttpEntity(json.toString(), headers)

    val response = restClient.postForObject(
            "https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyPassword?key=$testApiKey",
            request, Map::class.java) as Map<String, String>

    return response["idToken"]!!
}

但这不起作用,因为检索到的令牌缺少必需的颁发者字段。

标签: javafirebasefirebase-authentication

解决方案


推荐阅读