快速入門:從 Android 應用程式登入使用者並呼叫 Microsoft Graph
在本快速入門中,您會下載並執行程式碼範例,該範例會示範 Android 應用程式如何登入使用者,並取得存取權杖來呼叫 Microsoft Graph API。
應用程式必須以 Microsoft Entra ID 中的應用程式物件表示,讓 Microsoft 身分識別平台能夠為您的應用程式提供權杖。
必要條件
- 具有有效訂用帳戶的 Azure 帳戶。 免費建立帳戶。
- Android Studio
- Android 16+
此範例的運作方式
程式碼會組織成片段,說明如何撰寫單一和多重帳戶 MSAL 應用程式。 程式碼檔案的組織方式如下:
檔案 | 示範 |
---|---|
MainActivity | 管理 UI |
MSGraphRequestWrapper | 使用 MSAL 所提供的權杖來呼叫 Microsoft Graph API |
MultipleAccountModeFragment | 初始化多重帳戶應用程式、載入使用者帳戶,並取得權杖以呼叫 Microsoft Graph API |
SingleAccountModeFragment | 初始化單一帳戶應用程式、載入使用者帳戶,並取得權杖以呼叫 Microsoft Graph API |
res/auth_config_multiple_account.json | 多重帳戶組態檔 |
res/auth_config_single_account.json | 單一帳戶組態檔 |
Gradle Scripts/build.grade (Module:app) | 在此會新增 MSAL 程式庫相依性 |
現在我們將更詳細地探討這些檔案,並呼叫在每個檔案中 MSAL 特有的程式碼。
取得範例應用程式
註冊範例應用程式
提示
根據您開始使用的入口網站,本文中的步驟可能略有不同。
至少以應用程式開發人員的身分登入 Microsoft Entra 系統管理中心。
如果您有多個租用戶的存取權,請使用頂端功能表中的設定圖示
,從 [目錄 + 訂用帳戶] 功能表來切換要在其中註冊應用程式的租用戶。
瀏覽至 [身分識別]> [應用程式]> [應用程式註冊]。
選取新增註冊。
輸入應用程式的名稱。 您的應用程式使用者可能會看到此名稱,而且您稍後可以加以變更。
針對 [支援的帳戶類型],選取 [任何組織目錄中的帳戶 (任何 Microsoft Entra 目錄 - 多租用戶) 和個人 Microsoft 帳戶 (例如 Skype、Xbox)]。 如需不同帳戶類型的資訊,請選取 [協助我選擇] 選項。
選取註冊。
在 [管理] 底下,選取 [驗證]>[新增平台]>[Android]。
根據您下載的範例類型,輸入您的專案的套件名稱。
- JAVA 範例-
com.azuresamples.msalandroidapp
- Kotlin 範例 -
com.azuresamples.msalandroidkotlinapp
- JAVA 範例-
在 [設定您的 Android 應用程式] 頁面的 [簽章雜湊] 區段中,選取 [產生開發簽章雜湊。],然後將 KeyTool 命令複製到命令列。
- KeyTool.exe 會安裝為 Java 開發套件 (JDK) 的一部分。 您也必須安裝 OpenSSL 工具來執行 KeyTool 命令。 如需詳細資訊,請參閱關於產生金鑰的 Android 文件。
輸入 KeyTool 所產生的簽章雜湊。
選取 [設定] 並儲存出現在 [Android 組態] 窗格中的 [MSAL 組態],以便稍後在設定應用程式時可加以輸入。
選取完成。
設定範例應用程式
在 Android Studio 的專案窗格中,瀏覽至 app\src\main\res。
以滑鼠右鍵按一下 [res],然後選擇 [新增]>[目錄]。 輸入
raw
作為新的目錄名稱,然後選取 [確定]。在 [app]>[src]>[main]>[res]>[raw] 中,移至名為
auth_config_single_account.json
的新 JSON 檔案,並貼上您先前儲存的 [MSAL 設定]。在 [重新導向 URI] 下方,貼上:
"account_mode" : "SINGLE",
您的組態檔應會與下列範例類似:
{ "client_id": "00001111-aaaa-bbbb-3333-cccc4444", "authorization_user_agent": "WEBVIEW", "redirect_uri": "msauth://com.azuresamples.msalandroidapp/00001111%cccc4444%3D", "broker_redirect_uri_registered": true, "account_mode": "SINGLE", "authorities": [ { "type": "AAD", "audience": { "type": "AzureADandPersonalMicrosoftAccount", "tenant_id": "common" } } ] }
執行範例應用程式
從 Android Studio 的可用裝置下拉式清單中選取您的模擬器或實體裝置,然後執行應用程式。
範例應用程式會在 [單一帳戶模式] 畫面上啟動。 依預設會提供預設範圍 user.read,這是在 Microsoft Graph API 呼叫期間讀取您自己的設定檔資料時所使用的範圍。 依預設會提供 Microsoft Graph API 呼叫的 URL。 您可以視需要變更這兩項設定。
使用應用程式功能表,在單一和多重帳戶模式之間進行變更。
在單一帳戶模式中,使用工作或主帳戶登入:
- 選取 [以互動方式取得圖形資料],以提示使用者輸入其認證。 您會在畫面底部看到 Microsoft Graph API 呼叫的輸出。
- 登入之後,選取 [以無訊息方式取得圖形資料] 以呼叫 Microsoft Graph API,而不再次提示使用者提供認證。 您會在畫面底部看到 Microsoft Graph API 呼叫的輸出。
在多重帳戶模式中,您可以重複相同的步驟。 此外,您也可以移除已登入的帳戶,這也會移除該帳戶的快取權杖。
相關資訊
請閱讀這些小節以深入了解本快速入門。
將 MSAL 新增至應用程式
MSAL (com.microsoft.identity.client) 這個程式庫是用來登入使用者並要求權杖,該權杖會用來存取受 Microsoft 身分識別平台保護的 API。 當您在 [Gradle Scripts]>[build.gradle (Module: app)] 中的 [相依性] 底下新增以下內容時,Gradle 3.0+ 就會安裝該程式庫:
dependencies {
...
implementation 'com.microsoft.identity.client:msal:5.1.0'
implementation 'com.android.volley:volley:1.2.1'
...
}
這會指示 Gradle 從 Maven 中央存放庫下載並建置 MSAL。
您還必須將對 maven 的參考新增至 dependencyResolutionManagement 下的 settings.gradle (Module: app) 的 allprojects> 存放庫部分:
dependencyResolutionManagement {
...
maven
{
url 'https://pkgs.dev.azure.com/MicrosoftDeviceSDK/DuoSDK-Public/_packaging/Duo-SDK-Feed/maven/v1'
}
...
}
MSAL 匯入
與 MSAL 程式庫相關的匯入為 com.microsoft.identity.client.*
。 例如,您會看到 import com.microsoft.identity.client.PublicClientApplication;
,這是 PublicClientApplication
類別的命名空間,代表您的公用用戶端應用程式。
SingleAccountModeFragment.java
此檔案示範如何建立單一帳戶 MSAL 應用程式,並呼叫 Microsoft Graph API。
單一帳戶應用程式僅供單一使用者使用。 例如,您可能只會有一個用來登入對應應用程式的帳戶。
單一帳戶 MSAL 初始化
在 SingleAccountModeFragment.java
,在 onCreateView()
方法中,儲存在 auth_config_single_account.json
檔案中的組態資訊會用來建立單一帳戶 PublicClientApplication
。 這就是您初始化 MSAL 程式庫以供單一帳戶 MSAL 應用程式使用的方式:
...
// Creates a PublicClientApplication object with res/raw/auth_config_single_account.json
PublicClientApplication.createSingleAccountPublicClientApplication(getContext(),
R.raw.auth_config_single_account,
new IPublicClientApplication.ISingleAccountApplicationCreatedListener() {
@Override
public void onCreated(ISingleAccountPublicClientApplication application) {
/**
* This test app assumes that the app is only going to support one account.
* This requires "account_mode" : "SINGLE" in the config json file.
**/
mSingleAccountApp = application;
loadAccount();
}
@Override
public void onError(MsalException exception) {
displayError(exception);
}
});
登入使用者
在 SingleAccountModeFragment.java
中,用來登入使用者的程式碼位於 initializeUI()
的 signInButton
點擊處理常式中。
在嘗試取得權杖前,請先呼叫 signIn()
。 signIn()
的行為會如同呼叫了 acquireToken()
,而對登入的使用者產生互動式提示。
使用者登入是非同步作業。 在使用者登入後,會傳遞呼叫 Microsoft Graph API 的回呼,並更新 UI:
mSingleAccountApp.signIn(getActivity(), null, getScopes(), getAuthInteractiveCallback());
登出使用者
在 SingleAccountModeFragment.java
中,用來登出使用者的程式碼位於 initializeUI()
的 signOutButton
點擊處理常式中。 將使用者登出是非同步作業。 將使用者登出後,也會清除該帳戶的權杖快取。 當使用者帳戶登出後,會建立一個更新 UI 的回呼:
mSingleAccountApp.signOut(new ISingleAccountPublicClientApplication.SignOutCallback() {
@Override
public void onSignOut() {
updateUI(null);
performOperationOnSignOut();
}
@Override
public void onError(@NonNull MsalException exception) {
displayError(exception);
}
});
以互動或無訊息方式取得權杖
若要向使用者呈現最少的提示數,您通常會以無訊息方式取得權杖。 然後,如果發生錯誤,請嘗試以互動方式取得權杖。 應用程式第一次呼叫 signIn()
時,會有效地作為 acquireToken()
的呼叫,這會提示使用者提供認證。
在某些情況下,可能會提示使用者選取其帳戶、輸入認證,或同意應用程式要求的權限,這些情況包括:
- 使用者第一次登入應用程式時
- 如果使用者重設自己的密碼,就必須輸入自己的認證
- 如果已撤銷同意
- 如果您的應用程式明確要求同意
- 您的應用程式第一次要求存取資源時
- 需要 MFA 或其他條件式存取原則時
以互動方式 (即使用者使用 UI 的方式) 取得權杖的程式碼位於 SingleAccountModeFragment.java
、initializeUI()
、callGraphApiInteractiveButton
按一下處理常式中:
/**
* If acquireTokenSilent() returns an error that requires an interaction (MsalUiRequiredException),
* invoke acquireToken() to have the user resolve the interrupt interactively.
*
* Some example scenarios are
* - password change
* - the resource you're acquiring a token for has a stricter set of requirement than your Single Sign-On refresh token.
* - you're introducing a new scope which the user has never consented for.
**/
mSingleAccountApp.acquireToken(getActivity(), getScopes(), getAuthInteractiveCallback());
如果使用者已經登入,acquireTokenSilentAsync()
可讓應用程式以無訊息方式在 callGraphApiSilentButton
點擊處理常式中要求權杖,如 initializeUI()
中所說明:
/**
* Once you've signed the user in,
* you can perform acquireTokenSilent to obtain resources without interrupting the user.
**/
mSingleAccountApp.acquireTokenSilentAsync(getScopes(), AUTHORITY, getAuthSilentCallback());
載入帳戶
載入帳戶的程式碼位於 SingleAccountModeFragment.java
的 loadAccount()
中。 載入使用者的帳戶是非同步作業,因此會將在帳戶載入、變更或發生錯誤時予以處理的回呼傳至 MSAL。 下列程式碼也會處理 onAccountChanged()
,此情況會在移除帳戶、使用者變更為另一個帳戶時發生。
private void loadAccount() {
...
mSingleAccountApp.getCurrentAccountAsync(new ISingleAccountPublicClientApplication.CurrentAccountCallback() {
@Override
public void onAccountLoaded(@Nullable IAccount activeAccount) {
// You can use the account data to update your UI or your app database.
updateUI(activeAccount);
}
@Override
public void onAccountChanged(@Nullable IAccount priorAccount, @Nullable IAccount currentAccount) {
if (currentAccount == null) {
// Perform a cleanup task as the signed-in account changed.
performOperationOnSignOut();
}
}
@Override
public void onError(@NonNull MsalException exception) {
displayError(exception);
}
});
呼叫 Microsoft Graph
當使用者登入時,對 Microsoft Graph 的呼叫會透過 callGraphAPI()
所要求的 HTTP 來進行,其定義位於 SingleAccountModeFragment.java
中。 此函式是一個包裝函式,可藉由執行如下的工作來簡化範例:從 authenticationResult
取得存取權杖,並將呼叫封裝至 MSGraphRequestWrapper,以及顯示呼叫的結果。
private void callGraphAPI(final IAuthenticationResult authenticationResult) {
MSGraphRequestWrapper.callGraphAPIUsingVolley(
getContext(),
graphResourceTextView.getText().toString(),
authenticationResult.getAccessToken(),
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) {
...
}
});
}
auth_config_single_account.json
這是使用單一帳戶的 MSAL 應用程式的組態檔。
如需這些欄位的說明,請參閱了解 Android MSAL 設定檔。
請注意 "account_mode" : "SINGLE"
的存在,這會將此應用程式設定為使用單一帳戶。
"client_id"
已預先設定為使用 Microsoft 維護的應用程式物件註冊。
"redirect_uri"
已預先設定為使用程式碼範例所提供的簽署金鑰。
{
"client_id": "00001111-aaaa-2222-bbbb-3333cccc4444",
"authorization_user_agent": "WEBVIEW",
"redirect_uri": "msauth://com.azuresamples.msalandroidapp/1wIqXSqBj7w%2Bh11ZifsnqwgyKrY%3D",
"account_mode": "SINGLE",
"broker_redirect_uri_registered": true,
"authorities": [
{
"type": "AAD",
"audience": {
"type": "AzureADandPersonalMicrosoftAccount",
"tenant_id": "common"
}
}
]
}
MultipleAccountModeFragment.java
此檔案示範如何建立多重帳戶 MSAL 應用程式,並呼叫 Microsoft Graph API。
舉例來說,可讓您使用多個使用者帳戶 (例如工作帳戶和個人帳戶) 的電子郵件應用程式,即為多重帳戶應用程式。
多重帳戶 MSAL 初始化
在 MultipleAccountModeFragment.java
檔案的 onCreateView()
中,儲存在 auth_config_multiple_account.json file
中的組態資訊會用來建立多重帳戶應用程式物件 (IMultipleAccountPublicClientApplication
):
// Creates a PublicClientApplication object with res/raw/auth_config_multiple_account.json
PublicClientApplication.createMultipleAccountPublicClientApplication(getContext(),
R.raw.auth_config_multiple_account,
new IPublicClientApplication.IMultipleAccountApplicationCreatedListener() {
@Override
public void onCreated(IMultipleAccountPublicClientApplication application) {
mMultipleAccountApp = application;
loadAccounts();
}
@Override
public void onError(MsalException exception) {
...
}
});
建立的 MultipleAccountPublicClientApplication
物件會儲存在類別成員變數中,以便用來與 MSAL 程式庫互動,而取得權杖以及載入和移除使用者帳戶。
載入帳戶
多重帳戶應用程式通常會呼叫 getAccounts()
,以選取要用於 MSAL 作業的帳戶。 載入帳戶的程式碼位於 MultipleAccountModeFragment.java
檔案的 loadAccounts()
中。 載入使用者帳戶是非同步作業。 因此,會以回呼處理帳戶載入、變更或發生錯誤時的情況。
/**
* Load currently signed-in accounts, if there's any.
**/
private void loadAccounts() {
if (mMultipleAccountApp == null) {
return;
}
mMultipleAccountApp.getAccounts(new IPublicClientApplication.LoadAccountsCallback() {
@Override
public void onTaskCompleted(final List<IAccount> result) {
// You can use the account data to update your UI or your app database.
accountList = result;
updateUI(accountList);
}
@Override
public void onError(MsalException exception) {
displayError(exception);
}
});
}
以互動或無訊息方式取得權杖
在某些情況下,可能會提示使用者選取其帳戶、輸入認證,或同意應用程式要求的權限,這些情況包括:
- 使用者首次登入應用程式
- 如果使用者重設自己的密碼,就必須輸入自己的認證
- 如果已撤銷同意
- 如果您的應用程式明確要求同意
- 您的應用程式第一次要求存取資源時
- 需要 MFA 或其他條件式存取原則時
多重帳戶應用程式通常應以互動方式取得權杖,也就是使用者必須使用 UI,並呼叫 acquireToken()
。 在 MultipleAccountModeFragment.java
檔案中,以互動方式取得權杖的程式碼位於 initializeUI()
的 callGraphApiInteractiveButton
點擊處理常式中:
/**
* Acquire token interactively. It will also create an account object for the silent call as a result (to be obtained by getAccount()).
*
* If acquireTokenSilent() returns an error that requires an interaction,
* invoke acquireToken() to have the user resolve the interrupt interactively.
*
* Some example scenarios are
* - password change
* - the resource you're acquiring a token for has a stricter set of requirement than your SSO refresh token.
* - you're introducing a new scope which the user has never consented for.
**/
mMultipleAccountApp.acquireToken(getActivity(), getScopes(), getAuthInteractiveCallback());
應用程式應該不需要使用者在每次要求權杖時都必須登入。 如果使用者已經登入,acquireTokenSilentAsync()
可讓應用程式要求權杖,而不會對使用者發出提示,如 MultipleAccountModeFragment.java
中 initializeUI()
的 callGraphApiSilentButton
點擊處理常式所示:
/**
* Performs acquireToken without interrupting the user.
*
* This requires an account object of the account you're obtaining a token for.
* (can be obtained via getAccount()).
*/
mMultipleAccountApp.acquireTokenSilentAsync(getScopes(),
accountList.get(accountListSpinner.getSelectedItemPosition()),
AUTHORITY,
getAuthSilentCallback());
移除帳戶
在 MultipleAccountModeFragment.java
檔案的 initializeUI()
中,移除帳戶 (包含帳戶的任何快取權杖) 所用的程式碼位在用於移除帳戶按鈕的處理常式中。 您必須要有從 MSAL 方法 (如 getAccounts()
和 acquireToken()
) 取得的帳戶物件,才能移除帳戶。 由於移除帳戶是非同步作業,因此會提供 onRemoved
回呼以更新 UI。
/**
* Removes the selected account and cached tokens from this app (or device, if the device is in shared mode).
**/
mMultipleAccountApp.removeAccount(accountList.get(accountListSpinner.getSelectedItemPosition()),
new IMultipleAccountPublicClientApplication.RemoveAccountCallback() {
@Override
public void onRemoved() {
...
/* Reload account asynchronously to get the up-to-date list. */
loadAccounts();
}
@Override
public void onError(@NonNull MsalException exception) {
displayError(exception);
}
});
auth_config_multiple_account.json
這是使用多個帳戶的 MSAL 應用程式的組態檔。
如需各種欄位的說明,請參閱了解 Android MSAL 設定檔。
不同於 auth_config_single_account.json 組態檔,此組態檔具有 "account_mode" : "MULTIPLE"
(而非 "account_mode" : "SINGLE"
),因為這是多重帳戶應用程式。
"client_id"
已預先設定為使用 Microsoft 維護的應用程式物件註冊。
"redirect_uri"
已預先設定為使用程式碼範例所提供的簽署金鑰。
{
"client_id": "00001111-aaaa-2222-bbbb-3333cccc4444",
"authorization_user_agent": "WEBVIEW",
"redirect_uri": "msauth://com.azuresamples.msalandroidapp/1wIqXSqBj7w%2Bh11ZifsnqwgyKrY%3D",
"account_mode": "MULTIPLE",
"broker_redirect_uri_registered": true,
"authorities": [
{
"type": "AAD",
"audience": {
"type": "AzureADandPersonalMicrosoftAccount",
"tenant_id": "common"
}
}
]
}
說明與支援
如果您需要協助、想要回報問題,或想要深入了解您的支援選項,請參閱 開發人員的協助與支援。
下一步
繼續進行 Android 教學課程,您可以在其中建置 Android 應用程式,從 Microsoft 身分識別平台取得存取權杖,並將其用來呼叫 Microsoft Graph API。