チュートリアル: ネイティブ認証を使用して Android アプリで API を呼び出す

適用対象: 次の内容が外部テナントに適用されることを示す白いチェック マーク記号が付いた緑の円。 外部テナント (詳細)

このチュートリアルでは、アクセス トークンを取得し、Android モバイル アプリで API を呼び出す方法について説明します。 Android 用 Microsoft Authentication Library (MSAL) ネイティブ認証 SDK を使用すると、シングル サインインで複数のアクセス トークンを取得できます。 この機能を使用すると、ユーザーに再認証を要求する必要なく、1 つ以上のアクセス トークンを取得できます。

このチュートリアルでは、次の操作を行います。

  • 1 つまたは複数のアクセス トークンを取得します。
  • 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. 次のコード スニペットを使用して、1 つまたは複数のアクセス トークンを取得します。

    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 2 番目の 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 を呼び出すカスタム認証拡張機能で構成されています。

「外部システムからの要求をセキュリティ トークンに追加するように カスタム要求プロバイダーを構成 する」の手順に従います。