教學課程:在 Android (Kotlin) 行動應用程式中登入使用者
這是教學課程系列中的第三個教學課程,會引導您使用 Microsoft Entra 外部 ID 登入使用者。
在本教學課程中,您將會:
- 登入使用者
- 登出使用者
必要條件
登入使用者
使用適用於 Android 的 Microsoft 驗證程式庫 (MSAL) 登入使用者有兩個主要選項:以互動方式或以無訊息方式取得權杖。
若要以互動方式登入使用者,請使用下列程式碼:
private fun acquireTokenInteractively() { binding.txtLog.text = "" if (account != null) { Toast.makeText(this, "An account is already signed in.", Toast.LENGTH_SHORT).show() return } /* Extracts a scope array from text, i.e. from "User.Read User.ReadWrite" to ["user.read", "user.readwrite"] */ val scopes = scopes.lowercase().split(" ") val parameters = AcquireTokenParameters.Builder() .startAuthorizationFromActivity(this@MainActivity) .withScopes(scopes) .withCallback(getAuthInteractiveCallback()) .build() authClient.acquireToken(parameters) }
程式碼會使用適用於 Android 的 MSAL,以互動方式起始取得權杖的程序。 程序會先清除文字記錄欄位, 接著會檢查是否有已登入的帳戶,如果有,則會顯示快顯通知訊息,指出帳戶已經登入並傳回。
接下來,程序會從文字輸入擷取範圍,並將其轉換成小寫,然後再分割成陣列。 程序會使用這些範圍建置參數來取得權杖,包括從目前活動啟動授權程序,以及指定回撥。 最後,程序會在驗證用戶端上使用已建構的參數呼叫
acquireToken()
,以起始權杖擷取程序。在程式碼中,我們在其中指定回撥,使用稱為
getAuthInteractiveCallback()
的函式。 函式應該具有下列程式碼:private fun getAuthInteractiveCallback(): AuthenticationCallback { return object : AuthenticationCallback { override fun onSuccess(authenticationResult: IAuthenticationResult) { /* Successfully got a token, use it to call a protected resource - Web API */ Log.d(TAG, "Successfully authenticated") Log.d(TAG, "ID Token: " + authenticationResult.account.claims?.get("id_token")) Log.d(TAG, "Claims: " + authenticationResult.account.claims /* Reload account asynchronously to get the up-to-date list. */ CoroutineScope(Dispatchers.Main).launch { accessToken = authenticationResult.accessToken getAccount() binding.txtLog.text = getString(R.string.log_token_interactive) + accessToken } } override fun onError(exception: MsalException) { /* Failed to acquireToken */ Log.d(TAG, "Authentication failed: $exception") accessToken = null binding.txtLog.text = getString(R.string.exception_authentication) + exception if (exception is MsalClientException) { /* Exception inside MSAL, more info inside MsalError.java */ } else if (exception is MsalServiceException) { /* Exception when communicating with the STS, likely config issue */ } } override fun onCancel() { /* User canceled the authentication */ Log.d(TAG, "User cancelled login."); } } }
該程式碼片段會定義函式
getAuthInteractiveCallback
,用於傳回AuthenticationCallback
的執行個體。 在此函式中,將會建立實作AuthenticationCallback
介面的匿名類別。驗證成功時 (
onSuccess
),程式碼會記錄成功的驗證、擷取識別碼權杖和宣告、使用CoroutineScope
以非同步方式更新存取權杖,並使用新的存取權杖來更新 UI。 程式碼會從authenticationResult
擷取識別碼權杖並加以記錄。 權杖中的宣告包含使用者的相關資訊,例如其名稱、電子郵件或其他設定檔資訊。 您可以存取authenticationResult.account.claims
來擷取與目前帳戶相關聯的宣告。如果有驗證錯誤 (
onError
),程式碼會記錄錯誤、清除存取權杖、使用錯誤訊息更新 UI,以及針對MsalClientException
和MsalServiceException
提供更具體的處理。 如果使用者取消驗證 (onCancel
),則程式碼會記錄取消。請確定您包含 import 陳述式。 Android Studio 應該會自動包含 import 陳述式。
若要以無訊息方式登入使用者,請使用下列程式碼:
private fun acquireTokenSilently() { binding.txtLog.text = "" if (account == null) { Toast.makeText(this, "No account available", Toast.LENGTH_SHORT).show() return } /* Extracts a scope array from text, i.e. from "User.Read User.ReadWrite" to ["user.read", "user.readwrite"] */ val scopes = scopes.lowercase().split(" ") val parameters = AcquireTokenSilentParameters.Builder() .forAccount(account) .fromAuthority(account!!.authority) .withScopes(scopes) .forceRefresh(false) .withCallback(getAuthSilentCallback()) .build() authClient.acquireTokenSilentAsync(parameters) }
程式碼會以無訊息方式起始取得權杖的程序。 首先會清除文字記錄檔, 接著檢查是否有可用的帳戶;如果沒有,則會顯示一則快顯通知訊息,指出此情況並結束。 接下來,程序會從文字輸入擷取範圍、將其轉換成小寫,並分割成陣列。
程序會使用這些範圍建構參數,以無訊息方式取得權杖,並指定帳戶、授權單位、範圍和回撥。 最後,程序會在驗證用戶端上使用已建構的參數以非同步方式觸發
acquireTokenSilentAsync()
,開始無訊息權杖擷取程序。在程式碼中,我們在其中指定回撥,使用稱為
getAuthSilentCallback()
的函式。 函式應該具有下列程式碼:private fun getAuthSilentCallback(): SilentAuthenticationCallback { return object : SilentAuthenticationCallback { override fun onSuccess(authenticationResult: IAuthenticationResult?) { Log.d(TAG, "Successfully authenticated") /* Display Access Token */ accessToken = authenticationResult?.accessToken binding.txtLog.text = getString(R.string.log_token_silent) + accessToken } override fun onError(exception: MsalException?) { /* Failed to acquireToken */ Log.d(TAG, "Authentication failed: $exception") accessToken = null binding.txtLog.text = getString(R.string.exception_authentication) + exception when (exception) { is MsalClientException -> { /* Exception inside MSAL, more info inside MsalError.java */ } is MsalServiceException -> { /* Exception when communicating with the STS, likely config issue */ } is MsalUiRequiredException -> { /* Tokens expired or no session, retry with interactive */ } } } } }
此程式碼會定義無訊息驗證的回撥, 實作
SilentAuthenticationCallback
介面,並覆寫兩種方法。 在onSuccess
方法中,程序會記錄成功的驗證,並顯示存取權杖。在
onError
方法中,程序會記錄驗證失敗、處理不同類型的例外狀況 (例如MsalClientException
和MsalServiceException
),並視需要建議使用互動式驗證重試。請確定您包含 import 陳述式。 Android Studio 應該會自動包含 import 陳述式。
登出
若要使用適用於 Android 的 MSAL 從 Android (Kotlin) 應用程式登出使用者,請使用下列程式碼:
private fun removeAccount() {
binding.userName.text = ""
binding.txtLog.text = ""
authClient.signOut(signOutCallback())
}
此程式碼會從應用程式移除帳戶, 並清除顯示的使用者名稱和文字記錄檔。 然後,程式碼會使用驗證用戶端觸發登出程式,並指定登出回撥來處理登出作業的完成。
在程式碼中,我們在其中指定回撥,使用稱為 signOutCallback()
的函式。 函式應該具有下列程式碼:
private fun signOutCallback(): ISingleAccountPublicClientApplication.SignOutCallback {
return object : ISingleAccountPublicClientApplication.SignOutCallback {
override fun onSignOut() {
account = null
updateUI(account)
}
override fun onError(exception: MsalException) {
binding.txtLog.text = getString(R.string.exception_remove_account) + exception
}
}
}
此程式碼會為公用用戶端應用程式中的單一帳戶定義登出回撥, 實作 ISingleAccountPublicClientApplication.SignOutCallback
介面,並覆寫兩種方法。
在 onSignOut
方法中,程序會讓目前的帳戶為 Null,並對使用者介面進行相應更新。 在 onError
方法中,程序會記錄登出程序期間發生的任何錯誤,並使用對應的例外狀況訊息更新文字記錄檔。
請確定您包含 import 陳述式。 Android Studio 應該會自動包含 import 陳述式。