共用方式為


從行動應用程式呼叫 Web API

您的應用程式登入使用者並接收令牌之後,Microsoft 驗證連結庫 (MSAL) 會公開使用者、用戶環境和已發行令牌的相關信息。 您的應用程式可以使用這些值來呼叫 Web API,或向使用者顯示歡迎訊息。

在本文中,我們將先查看 MSAL 結果。 然後,我們將探討如何使用 或 resultAuthenticationResult存取令牌來呼叫受保護的 Web API。

MSAL 結果

MSAL 提供下列值:

  • AccessToken 在 HTTP 持有人要求中呼叫受保護的 Web API。
  • IdToken 包含登入使用者的相關實用資訊。 這項資訊包括用戶的名稱、主租使用者,以及記憶體的唯一標識碼。
  • ExpiresOn 是令牌的到期時間。 MSAL 會處理應用程式的自動重新整理。
  • TenantId 是使用者登入之租用戶的標識碼。 對於 Microsoft Entra B2B 中的來賓使用者,此值會識別使用者登入所在的租使用者。 此值不會識別使用者的主租使用者。
  • Scopes 表示使用令牌授與的範圍。 授與的範圍可能是您所要求範圍的子集。

MSAL 也提供值的抽象概念 Account 。 值 Account 代表目前使用者的登入帳戶:

  • HomeAccountIdentifier 識別使用者的主租使用者。
  • UserName 是使用者慣用的用戶名稱。 對於 Azure AD B2C 使用者而言,此值可能是空的。
  • AccountIdentifier 識別已登入的使用者。 在大部分情況下,除非使用者是另一個租使用者中的來賓,否則此值與值相同 HomeAccountIdentifier

呼叫 API

取得存取令牌之後,您可以呼叫 Web API。 您的應用程式會使用令牌來建置 HTTP 要求,然後執行要求。

Android

        RequestQueue queue = Volley.newRequestQueue(this);
        JSONObject parameters = new JSONObject();

        try {
            parameters.put("key", "value");
        } catch (Exception e) {
            // Error when constructing.
        }
        JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, MSGRAPH_URL,
                parameters,new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                // Successfully called Graph. Process data and send to UI.
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                // Error.
            }
        }) {
            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                Map<String, String> headers = new HashMap<>();

                // Put access token in HTTP request.
                headers.put("Authorization", "Bearer " + authResult.getAccessToken());
                return headers;
            }
        };

        request.setRetryPolicy(new DefaultRetryPolicy(
                3000,
                DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
        queue.add(request);

適用於 iOS 和 macOS 的 MSAL

取得令牌的方法會傳回 MSALResult 物件。 MSALResultaccessToken會公開 屬性。 您可以使用 accessToken 來呼叫 Web API。 在呼叫 以存取受保護的 Web API 之前,請先將此屬性新增至 HTTP 授權標頭。

NSMutableURLRequest *urlRequest = [NSMutableURLRequest new];
urlRequest.URL = [NSURL URLWithString:"https://contoso.api.com"];
urlRequest.HTTPMethod = @"GET";
urlRequest.allHTTPHeaderFields = @{ @"Authorization" : [NSString stringWithFormat:@"Bearer %@", accessToken] };

NSURLSessionDataTask *task =
[[NSURLSession sharedSession] dataTaskWithRequest:urlRequest
     completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {}];
[task resume];
let urlRequest = NSMutableURLRequest()
urlRequest.url = URL(string: "https://contoso.api.com")!
urlRequest.httpMethod = "GET"
urlRequest.allHTTPHeaderFields = [ "Authorization" : "Bearer \(accessToken)" ]

let task = URLSession.shared.dataTask(with: urlRequest as URLRequest) { (data: Data?, response: URLResponse?, error: Error?) in }
task.resume()

Xamarin

MSAL.NET 中的 AuthenticationResult 屬性

取得權杖的方法會傳回 AuthenticationResult。 針對異步方法, Task<AuthenticationResult> 會傳回 。

在 MSAL.NET 中, AuthenticationResult 公開:

  • AccessToken 供 Web API 存取資源。 此參數是字串,通常是Base-64編碼的JWT。 用戶端絕對不應該在存取令牌內查看。 格式不保證會保持穩定,而且可以加密資源。 撰寫依賴用戶端存取令牌內容的程式代碼,是錯誤和客戶端邏輯中斷的最大來源之一。 如需詳細資訊,請參閱 存取令牌
  • IdToken 使用者。 此參數是編碼的 JWT。 如需詳細資訊,請參閱 標識符令牌
  • ExpiresOn 告知令牌到期的日期和時間。
  • TenantId 包含找到使用者的租使用者。 針對 Microsoft Entra B2B 案例中的來賓使用者,租使用者標識碼是來賓租使用者,而不是唯一租使用者。 為用戶傳遞令牌時, AuthenticationResult 也包含此用戶的相關信息。 對於要求令牌且沒有應用程式使用者的機密用戶端流程,此使用者資訊為 null。
  • Scopes發出權杖的 。
  • 使用者的唯一識別碼。

IAccount

MSAL.NET 透過 IAccount 介面定義帳戶的概念。 這項重大變更提供正確的語意。 相同的用戶可以在不同的 Microsoft Entra 目錄中擁有數個帳戶。 此外,MSAL.NET 客體案例中提供更佳的信息,因為提供主帳戶資訊。 下圖顯示 介面的結構 IAccount

IAccount interface structure

類別 AccountId 會識別特定租使用者中的帳戶,其中包含下表所示的屬性。

屬性 說明
TenantId GUID 的字串表示,這是帳戶所在租用戶的標識碼。
ObjectId GUID 的字串表示,這是在租用戶中擁有帳戶的使用者標識碼。
Identifier 帳戶的唯一標識碼。 Identifier 是的 ObjectId 串連,並以 TenantId 逗號分隔。 它們不是Base 64編碼。

介面 IAccount 代表單一帳戶的相關信息。 相同的使用者可以存在於不同的租使用者中,這表示使用者可以有多個帳戶。 下表顯示其成員。

屬性 說明
Username 字串,包含 UserPrincipalName (UPN) 格式的可顯示值,例如 john.doe@contoso.com。 此字串可以是 null,不同於 HomeAccountId 和 HomeAccountId.Identifier,這不會是 Null。 這個屬性會 DisplayableId 取代舊版 MSAL.NET 中的屬性 IUser
Environment 字串,包含此帳戶的識別提供者,例如 login.microsoftonline.com。 這個屬性會 IdentityProvider 取代的 IUser屬性,但 IdentityProvider 除了雲端環境之外,也包含租用戶的相關信息。 在這裡,值只是主機。
HomeAccountId 使用者主帳戶的帳戶標識碼。 此屬性可唯一識別 Microsoft Entra 租用戶的使用者。

使用令牌來呼叫受保護的 API

在 中result由 MSAL 傳回 之後AuthenticationResult,請先將它新增至 HTTP 授權標頭,再進行呼叫以存取受保護的 Web API。

httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);

// Call the web API.
HttpResponseMessage response = await _httpClient.GetAsync(apiUri);
...
}

提出數個 API 要求

若要呼叫相同的 API 數次,或呼叫多個 API,請在建置應用程式時考慮下列主題:

  • 累加同意:Microsoft 身分識別平台 可讓應用程式在需要許可權時取得使用者同意,而不是在啟動時取得全部許可權。 每次您的應用程式準備好呼叫 API 時,都應該只要求它所需的範圍。

  • 條件式存取:當您提出數個 API 要求時,在某些情況下,您可能需要符合其他條件式存取需求。 如果第一個要求沒有條件式存取原則,而且您的應用程式嘗試以無訊息方式存取需要條件式存取的新 API,需求可能會以這種方式增加。 若要處理此問題,請務必從無訊息要求攔截錯誤,並準備好提出互動式要求。 如需詳細資訊,請參閱 條件式存取的指引。

若要為相同的使用者呼叫數個 API,在取得使用者的令牌之後,您可以藉由後續呼叫 AcquireTokenSilent 來取得令牌,避免重複要求使用者提供認證:

var result = await app.AcquireTokenXX("scopeApi1")
                      .ExecuteAsync();

result = await app.AcquireTokenSilent("scopeApi2")
                  .ExecuteAsync();

在下列情況下需要互動:

  • 使用者已同意第一個 API,但現在需要同意更多範圍。 在此情況下,您會使用累加式同意。
  • 第一個 API 不需要 多重要素驗證,但下一個 API 會執行。
var result = await app.AcquireTokenXX("scopeApi1")
                      .ExecuteAsync();

try
{
 result = await app.AcquireTokenSilent("scopeApi2")
                  .ExecuteAsync();
}
catch(MsalUiRequiredException ex)
{
 result = await app.AcquireTokenInteractive("scopeApi2")
                  .WithClaims(ex.Claims)
                  .ExecuteAsync();
}

下一步

請移至此案例中的下一篇文章, 移至生產環境