Tutorial: Inicio de sesión de usuarios en la aplicación móvil de iOS (Swift)
Este es el tercer tutorial de la serie de tutoriales que le guiará en el inicio de sesión de usuarios utilizando Id. externa de Microsoft Entra.
En este tutorial, hará lo siguiente:
- Usuario de inicio de sesión.
- Cerrar la sesión del usuario.
Requisitos previos
Inicio de sesión de los usuarios
Tiene dos opciones principales para iniciar sesión de usuarios mediante la Biblioteca de autenticación de Microsoft (MSAL) para iOS: adquirir tokens de forma interactiva o silenciosa.
Para iniciar sesión de forma interactiva, use el siguiente código:
acquireTokenInteractively() { guard let applicationContext = self.applicationContext else { return } guard let webViewParameters = self.webViewParamaters else { return } updateLogging(text: "Acquiring token interactively...") let parameters = MSALInteractiveTokenParameters(scopes: Configuration.kScopes, webviewParameters: webViewParameters) parameters.promptType = .selectAccount applicationContext.acquireToken(with: parameters) { (result, error) in if let error = error { self.updateLogging(text: "Could not acquire token: \(error)") return } guard let result = result else { self.updateLogging(text: "Could not acquire token: No result returned") return } self.accessToken = result.accessToken self.updateLogging(text: "Access token is \(self.accessToken)") self.updateCurrentAccount(account: result.account) } }
El código comprueba primero si los parámetros de contexto de aplicación y vista web están disponibles. A continuación, actualice el registro para indicar que adquiere el token de forma interactiva. A continuación, configure los parámetros para la adquisición interactiva de fichas, especificando los ámbitos y los parámetros de la vista web. También establece el tipo de aviso para seleccionar una cuenta.
Después, llama al método
acquireToken
en el contexto de la aplicación con los parámetros definidos. En el controlador de finalización, comprueba si hay errores. Si se produce un error, actualizará el registro con el mensaje de error. Si tiene éxito, recupera el token de acceso del resultado, actualiza el registro con el token y actualiza la cuenta actual.Una vez que su aplicación adquiere un token de acceso, puede recuperar las notificaciones asociadas a la cuenta corriente. Para ello, use el siguiente fragmento de código:
let claims = result.account.accountClaims let preferredUsername = claims?["preferred_username"] as? String
El código lee las notificaciones de la cuenta accediendo a la propiedad
accountClaims
del objetoresult.account
. A continuación, recupere el valor de la notificación "preferred_username" del diccionario de notificaciones y asígnelo a la variablepreferredUsername
.Para iniciar sesión de forma silenciosa, use el siguiente código:
func acquireTokenSilently() { self.loadCurrentAccount { (account) in guard let currentAccount = account else { self.updateLogging(text: "No token found, try to acquire a token interactively first") return } self.acquireTokenSilently(currentAccount) } }
El código inicia el proceso de adquisición de tokens de forma silenciosa. Primero intenta cargar la cuenta actual. Si se encuentra una cuenta corriente, se procede a adquirir el token de forma silenciosa utilizando dicha cuenta. Si no se encuentra ninguna cuenta corriente, actualiza el registro para indicar que no se ha encontrado ningún token y sugiere intentar adquirir primero un token de forma interactiva.
En el código anterior, llamamos a dos funciones,
loadCurrentAccount
yacquireTokenSilently
. La funciónloadCurrentAccount
debe tener el siguiente código:func loadCurrentAccount(completion: AccountCompletion? = nil) { guard let applicationContext = self.applicationContext else { return } let msalParameters = MSALParameters() msalParameters.completionBlockQueue = DispatchQueue.main // Note that this sample showcases an app that signs in a single account at a time applicationContext.getCurrentAccount(with: msalParameters, completionBlock: { (currentAccount, previousAccount, error) in if let error = error { self.updateLogging(text: "Couldn't query current account with error: \(error)") return } if let currentAccount = currentAccount { self.updateCurrentAccount(account: currentAccount) self.acquireTokenSilently(currentAccount) if let completion = completion { completion(self.currentAccount) } return } // If testing with Microsoft's shared device mode, see the account that has been signed out from another app. More details here: // https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-ios-shared-devices if let previousAccount = previousAccount { self.updateLogging(text: "The account with username \(String(describing: previousAccount.username)) has been signed out.") } else { self.updateLogging(text: "") } self.accessToken = "" self.updateCurrentAccount(account: nil) if let completion = completion { completion(nil) } }) }
El código usa MSAL para iOS para cargar la cuenta actual. Comprueba si hay errores y actualiza el registro en consecuencia. Si se encuentra una cuenta actual, la actualiza e intenta adquirir tokens de forma silenciosa. Si existe una cuenta anterior, registra el cierre de sesión. Si no se encuentra ninguna cuenta, borra el token de acceso. Por último, ejecuta un bloque de finalización si se proporciona.
La función
acquireTokenSilently
debe contener el siguiente código:func acquireTokenSilently(_ account : MSALAccount) { guard let applicationContext = self.applicationContext else { return } /** Acquire a token for an existing account silently - forScopes: Permissions you want included in the access token received in the result in the completionBlock. Not all scopes are guaranteed to be included in the access token returned. - account: An account object that we retrieved from the application object before that the authentication flow will be locked down to. - completionBlock: The completion block that will be called when the authentication flow completes, or encounters an error. */ updateLogging(text: "Acquiring token silently...") let parameters = MSALSilentTokenParameters(scopes: Configuration.kScopes, account: account) applicationContext.acquireTokenSilent(with: parameters) { (result, error) in if let error = error { let nsError = error as NSError // interactionRequired means we need to ask the user to sign-in. This usually happens // when the user's Refresh Token is expired or if the user has changed their password // among other possible reasons. if (nsError.domain == MSALErrorDomain) { if (nsError.code == MSALError.interactionRequired.rawValue) { DispatchQueue.main.async { self.acquireTokenInteractively() } return } } self.updateLogging(text: "Could not acquire token silently: \(error)") return } guard let result = result else { self.updateLogging(text: "Could not acquire token: No result returned") return } self.accessToken = result.accessToken self.updateLogging(text: "Refreshed Access token is \(self.accessToken)") self.updateSignOutButton(enabled: true) } }
Esta función usa MSAL para iOS para adquirir de forma silenciosa un token para una cuenta existente. Después de comprobar
applicationContext
, registra el proceso de adquisición de tokens. MedianteMSALSilentTokenParameters
, define los parámetros necesarios. A continuación, intenta adquirir el token de forma silenciosa. Si hay errores, comprueba si hay requisitos de interacción del usuario, iniciando un proceso interactivo si es necesario. Si tiene éxito, actualiza la propiedadaccessToken
y registra el token actualizado, finalizando con la activación del botón de cierre de sesión.
Cerrar la sesión del usuario
Para cerrar la sesión de un usuario de la aplicación de iOS (Swift) mediante MSAL para iOS, use el siguiente código:
@IBAction func signOut(_ sender: UIButton) {
guard let applicationContext = self.applicationContext else { return }
guard let account = self.currentAccount else { return }
guard let webViewParamaters = self.webViewParamaters else { return }
updateLogging(text: "Signing out...")
do {
/**
Removes all tokens from the cache for this application for the provided account
- account: The account to remove from the cache
*/
let signoutParameters = MSALSignoutParameters(webviewParameters: webViewParamaters)
// If testing with Microsoft's shared device mode, trigger signout from browser. More details here:
// https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-ios-shared-devices
if (self.currentDeviceMode == .shared) {
signoutParameters.signoutFromBrowser = true
} else {
signoutParameters.signoutFromBrowser = false
}
applicationContext.signout(with: account, signoutParameters: signoutParameters, completionBlock: {(success, error) in
if let error = error {
self.updateLogging(text: "Couldn't sign out account with error: \(error)")
return
}
self.updateLogging(text: "Sign out completed successfully")
self.accessToken = ""
self.updateCurrentAccount(account: nil)
})
}
}
El código comprueba la existencia del applicationContext
, currentAccount
y webViewParamaters
. A continuación, registra el proceso de cierre de sesión. El código quita todos los tokens de la memoria caché de la cuenta proporcionada. Dependiendo del modo de dispositivo actual, determina si se cierra sesión desde el explorador. Tras la finalización, actualiza el texto de registro en consecuencia. Si se produce un error durante el proceso de cierre de sesión, registra el mensaje de error. Tras cerrar la sesión correctamente, actualiza el token de acceso a una cadena vacía y borra la cuenta actual.
Pasos siguientes
Tutorial: llamar a una API web protegida en la aplicación iOS (Swift).