單一帳號與多帳號公共客戶端應用程式

本文將幫助你了解單一帳號與多帳號公共客戶端應用程式所使用的類型,特別聚焦於單一帳號公共客戶端應用程式。

Azure Active Directory 認證函式庫(ADAL)對伺服器進行建模。 而 Microsoft 驗證資源庫(MSAL)則是模擬您的客戶端應用程式。 大多數 Android 應用程式都被視為公開客戶端。 公開客戶端是指無法安全保守秘密的應用程式。

MSAL 專門針對 API 表面 PublicClientApplication 設計,簡化並釐清那些一次只能使用一個帳號的應用程式的開發體驗。 PublicClientApplication 的子類別包括 SingleAccountPublicClientApplicationMultipleAccountPublicClientApplication。 下圖展示了這些類別之間的關係。

SingleAccountPublicClientApplication UML Class Diagram

單一帳戶公開客戶端應用程式

SingleAccountPublicClientApplication 門課讓你可以建立一個基於 MSAL 的應用程式,一次只能登入一個帳號。 SingleAccountPublicClientApplication 與以下幾點不同 PublicClientApplication

  • MSAL 會追蹤目前已登入的帳號。
    • 如果你的應用程式使用經紀人(Microsoft Entra 應用程式註冊時的預設),且安裝在有經紀人的裝置上,MSAL 會驗證該帳號仍在該裝置上。
  • signIn 可讓你明確地登入帳戶,並將此操作與要求權限範圍分開。
  • acquireTokenSilent 不需要帳號參數。 如果你確實提供了帳戶,而你提供的帳戶與 MSAL 目前追蹤的帳戶不符,就會拋出 MsalClientException
  • acquireToken 不允許使用者切換帳號。 如果使用者嘗試切換到其他帳號,會拋出例外。
  • getCurrentAccount 回傳一個結果物件,提供以下內容:
    • 一個布林值,表示帳號是否變更。 例如,帳號可能因從裝置中移除而被更改。
    • 先前的帳戶。 如果你需要在帳號從裝置移除或新帳號登入時進行本地資料清理,這很有用。
    • 目前的帳戶。
  • signOut 移除裝置上與客戶端相關的所有標記。

當裝置安裝了 Android 認證代理工具,如 Microsoft Authenticator、Link to Windows(LTW)或 Intune 公司入口網站,且你的應用程式設定為使用該代理signOut,這些都不會將帳號從裝置中移除。

單一帳戶情境

以下偽代碼說明如何使用 SingleAccountPublicClientApplication

// Construct Single Account Public Client Application
ISingleAccountPublicClientApplication app = PublicClientApplication.createSingleAccountPublicClientApplication(getApplicationContext(), R.raw.msal_config);

String[] scopes = {"User.Read"};
IAccount mAccount = null;

// Acquire a token interactively
// The user will get a UI prompt before getting the token.
SignInParameters signInParameters = SignInParameters.builder()
        .withActivity(getActivity()) // Pass the current activity
        .withScopes(scopes) // Specify the scopes
        .withCallback(new AuthenticationCallback() {
            @Override
            public void onSuccess(IAuthenticationResult authenticationResult){
                mAccount = authenticationResult.getAccount();
            }
    
            @Override
            public void onError(MsalException exception){
            }
    
            @Override
            public void onCancel(){
            }
        })
        .build();


app.signIn(signInParameters);

// Load Account Specific Data
getDataForAccount(account);

// Get Current Account
ICurrentAccountResult currentAccountResult = app.getCurrentAccount();
if (currentAccountResult.didAccountChange()){
    // Account Changed Clear existing account data
    clearDataForAccount(currentAccountResult.getPriorAccount());
    mAccount = currentAccountResult.getCurrentAccount();
    if (account != null){
        //load data for new account
        getDataForAccount(account);
    }
}

// Sign out
if (app.signOut()) {
    clearDataForAccount(mAccount);
    mAccount = null;
}

多帳號公開客戶端應用程式

MultipleAccountPublicClientApplication 類別用於開發基於 MSAL 的應用程式,允許多個帳號同時登入。 它允許你依以下方式取得、新增及移除帳號:

新增帳戶

在您的應用程式中,透過呼叫 acquireToken 一次或多次來使用一個或多個帳戶。

取得帳戶

  • 打電話 getAccount 申請特定帳戶。
  • 打電話 getAccounts查詢目前應用程式已知的帳號清單。

你的應用程式將無法列舉代理應用程式已知之裝置上的所有 Microsoft 身分識別平台帳戶。 它只能列舉你的應用程式曾經使用的帳號。 這些功能不會讓被移除的帳號被還原。

拿掉帳戶

使用帳戶識別碼呼叫 removeAccount 以移除帳戶。

如果你的應用程式已設定為使用代理程式,且裝置上已安裝代理程式,當你呼叫 removeAccount 時,帳戶不會從代理程式中移除。 只有與你客戶端相關的代幣會被移除。

多帳號情境

以下的偽程式碼展示了如何建立多帳號應用程式、在裝置上列出帳號,以及取得代幣。

// Construct Multiple Account Public Client Application
IMultipleAccountPublicClientApplication app = PublicClientApplication.createMultipleAccountPublicClientApplication(getApplicationContext(), R.raw.msal_config);

String[] scopes = {"User.Read"};
IAccount mAccount = null;

// Acquire a token interactively
// The user will be required to interact with a UI to obtain a token
AcquireTokenParameters acquireTokenParameters = new AcquireTokenParameters.Builder()
        .startAuthorizationFromActivity(getActivity())
        .withScopes(scopes)
        .withCallback(new AuthenticationCallback(){
    
            @Override
            public void onSuccess(IAuthenticationResult authenticationResult) {
                mAccount = authenticationResult.getAccount();
            }
    
            @Override
            public void onError(MsalException exception){
            }
    
            @Override
            public void onCancel(){
            }
         })
        .build();
app.acquireToken(acquireTokenParameters);


...

// Get the default authority
String authority = app.getConfiguration().getDefaultAuthority().getAuthorityURL().toString();

// Get a list of accounts on the device
List<IAccount> accounts = app.getAccounts();

// Pick an account to obtain a token from without prompting the user to sign in
IAccount selectedAccount = accounts.get(0);

// Get a token without prompting the user
AcquireTokenSilentParameters acquireTokenSilentParameters = new AcquireTokenSilentParameters.Builder()
        .withScopes(scopes)
        .forAccount(selectedAccount)
        .fromAuthority(authority)
        .withCallback(new SilentAuthenticationCallback() {

            @Override
            public void onSuccess(IAuthenticationResult authenticationResult) {
                mAccount = authenticationResult.getAccount();
            }
    
            @Override
            public void onError(MsalException exception){
            }
        })
        .build();
app.acquireTokenSilentAsync(acquireTokenSilentParameters);