通过


教程:使用本机身份验证在 Android 应用中调用 API

适用于绿色圆圈,带有白色复选标记符号,指示以下内容适用于外部租户。 外部租户(了解详细信息

本教程介绍如何获取访问令牌并在 Android 移动应用中调用 API。 使用适用于 Android 的Microsoft身份验证库(MSAL)本机身份验证 SDK,可以使用单一登录获取多个访问令牌。 借助此功能,你可获取一个或多个访问令牌,而无需用户重新进行身份验证。

在本教程中,你将:

  • 获取一个或多个访问令牌。
  • 调用 API

先决条件

获取访问令牌

用户登录后,通过指定访问令牌有效的范围来获取访问令牌。

MSAL 本机身份验证 SDK 支持多个访问令牌,因此可以指定多个范围集,然后为每个范围集请求访问令牌:

  1. 使用以下代码片段声明和设置一组 API 范围的值:

    companion object {
        // Set values for respective API scopes for their web API resources here, for example: ["api://<Resource_App_ID>/ToDoList.Read", "api://<Resource_App_ID>/ToDoList.ReadWrite"]
        // A list of scope for API 1
        private val scopesForAPI1 = listOf<String>()
        // A list of scope for API 2
        private val scopesForAPI2 = listOf<String>()
    }
    
  2. 使用以下代码片段让用户登录:

    CoroutineScope(Dispatchers.Main).launch {
        val parameters = NativeAuthSignInParameters(username = email)
        parameters.password = password
        val actionResult: SignInResult = authClient.signIn(parameters)
    
        if (actionResult is SignInResult.Complete) -> {
            // Perform operations after successful sign-in
        } else if (actionResult is SignInError) {
            // Handle sign-in errors
        }
    }
    
  3. 使用以下代码片段获取一个或多个访问令牌:

    CoroutineScope(Dispatchers.Main).launch {
        val accountResult = authClient.getCurrentAccount()
        when (accountResult) {
            is GetAccountResult.AccountFound -> {
                try {
                    // Access token for API 1
                    val accessTokenOne = getAccessToken(accountResult.resultValue, scopesForAPI1)
                    // Access token for API 2
                    val accessTokenTwo = getAccessToken(accountResult.resultValue, scopesForAPI2)
                    // Proceed to make a call to an API
                } catch (e: Exception) {
                    // Handle Exception
                }
            }
            is GetAccountResult.NoAccountFound -> {
                // Handle etAccountResult.NoAccountFound
            }
            is GetAccountError -> {
                // Handle GetAccountError 
            }
        }
    }   
    
    

    getAccessToken()定义为如下代码所示的函数:

    private suspend fun getAccessToken(accountState: AccountState, scopes: List<String>): String {
        val parameters = NativeAuthGetAccessTokenParameters()
        parameters.scopes = scopes
        val accessTokenState = accountState.getAccessToken(parameters)
    
        return if (accessTokenState is GetAccessTokenResult.Complete) {
            accessTokenState.resultValue.accessToken
        } else {
            throw Exception("Failed to get access token")
        }
    }
    

调用 API

若要进行 API 调用,请使用在 获取访问令牌 和 API URL 中获取的访问令牌:

  1. 使用以下代码片段声明和设置 API URL 的值:

    companion object {
        // Set values for respective API scopes for web API resources here, for example: ["api://<Resource_App_ID>/ToDoList.Read", "api://<Resource_App_ID>/ToDoList.ReadWrite"]
        // A list of scope for API 1
        private val scopesForAPI1 = listOf<String>()
        // A list of scope for API 2
        private val scopesForAPI2 = listOf<String>()
        // Set the URL of first web API resource here
        private const val WEB_API_URL_1 = "Enter_URL_Of_First_Web_API" 
        // Set the URL of second web API resource here
        private const val WEB_API_URL_2 = "Enter_URL_Of_Second_Web_API" 
    }
    

    请替换以下内容:

    • Enter_URL_Of_First_Web_API 占位符替换为第一个 API 的完整 URL 值。
    • Enter_URL_Of_Second_Web_API 占位符替换为第二个 API 的完整 URL 值。
  2. 使用以下代码片段调用 API:

    // After you acquire an access token, use it to call an API
    
    val firstApiResponse = useAccessToken(WEB_API_URL_1, accessTokenOne)
    val secondApiResponse = useAccessToken(WEB_API_URL_2, accessTokenTwo)
    
    private suspend fun useAccessToken(WEB_API_URL: String, accessToken: String): Response {
        return withContext(Dispatchers.IO) {
            ApiClient.performGetApiRequest(WEB_API_URL, accessToken)
        }
    }
    

    performGetApiRequest()定义为如下代码所示的函数:

    object ApiClient {
        private val client = OkHttpClient()
    
        fun performGetApiRequest(WEB_API_URL: String, accessToken: String): Response {    
            val requestBuilder = Request.Builder()
                    .url(WEB_API_URL)
                    .addHeader("Authorization", "Bearer $accessToken")
                    .get()
    
            val request = requestBuilder.build()
    
            client.newCall(request).execute().use { response -> return response }
        }
    }
    

配置自定义声明提供程序

如果要将来自外部系统的声明添加到颁发给应用的令牌中,请使用自定义声明提供程序。 自定义声明提供程序由自定义身份验证扩展组成,它会调用外部 REST API 来从外部系统提取声明。

按照配置自定义声明提供程序中的步骤将外部系统中的声明添加到安全令牌中。