Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Se aplica a:
Inquilinos externos (más información)
En este tutorial, aprenderás a adquirir un token de acceso y a llamar a una API en la aplicación móvil iOS/macOS. El SDK de autenticación nativa de la biblioteca de autenticación de Microsoft (MSAL) para iOS/macOS te permite adquirir varios tokens de acceso con un inicio de sesión único. Esta funcionalidad te permite adquirir uno o varios tokens de acceso sin necesidad de que un usuario vuelva a autenticarse.
En este tutorial, harás lo siguiente:
- Adquirir uno o varios tokens de acceso.
- Llamada a una API
Prerrequisitos
- Completa los pasos que se describen en Inicio de sesión de usuarios y llamada a una API en una aplicación móvil iOS de muestra mediante la autenticación nativa.
- Completa los pasos descritos en Tutorial: Incorporación de inicio y cierre de sesión en la aplicación iOS/macOS mediante la autenticación nativa. En este tutorial se muestra cómo iniciar la sesión de los usuarios en la aplicación iOS/macOS mediante la autenticación nativa.
Adquiere uno o varios tokens de acceso.
El SDK de autenticación nativa de MSAL puede almacenar varios tokens de acceso. Después de iniciar sesión, puedes obtener un token de acceso usando la función getAccessToken(parameters:) y especificando los ámbitos para el nuevo token de acceso que quieres conceder.
Declara y establece valores para un conjunto de ámbitos de API mediante el siguiente fragmento de código:
let protectedAPIUrl1: String? = nil let protectedAPIUrl2: String? = nil let protectedAPIScopes1: [String] = [] let protectedAPIScopes2: [String] = [] var accessTokenAPI1: String? var accessTokenAPI2: String?- Inicializa
protectedAPIUrl1con la dirección URL de la primera API web. - Inicializa
protectedAPIUrl2con la dirección URL de la segunda API web. - Define
protectedAPIScopes1con ámbitos para tu primera API, como["api://<Resource_App_ID>/ToDoList.Read", "api://<Resource_App_ID>/ToDoList.ReadWrite"]. - Define
protectedAPIScopes2con ámbitos para la segunda API, similar aprotectedAPIScopes1. - Declara las variables de cadena opcionales
accessTokenAPI1yaccessTokenAPI2.
- Inicializa
Inicia la sesión del usuario mediante el siguiente fragmento de código:
@IBAction func signInPressed(_: Any) { guard let email = emailTextField.text, let password = passwordTextField.text else { resultTextView.text = "Email or password not set" return } print("Signing in with email \(email) and password") showResultText("Signing in...") let parameters = MSALNativeAuthSignInParameters(username: email) parameters.password = password nativeAuth.signIn(parameters: parameters, delegate: self) }El método
signInPressedcontrola la pulsación del botón de inicio de sesión. Comprueba si han rellenado los campos de correo electrónico y contraseña. Si alguno de los campos está vacío, muestra "Correo electrónico o contraseña no establecida". Si ambos campos se han rellenado, registra el correo electrónico, muestra "Iniciando sesión..." e inicia el inicio de sesión con el métodosignIndenativeAuthcon el correo electrónico y la contraseña proporcionados. El SDK recupera un token válido para los ámbitos OIDC predeterminados (openid, offline_access y profile) porque no se especifica ningún ámbito.Adquiere uno o varios tokens de acceso mediante el siguiente fragmento de código:
@IBAction func protectedApi1Pressed(_: Any) { guard let url = protectedAPIUrl1, !protectedAPIScopes1.isEmpty else { showResultText("API 1 not configured.") return } if let accessToken = accessTokenAPI1 { accessProtectedAPI(apiUrl: url, accessToken: accessToken) } else { let parameters = MSALNativeAuthGetAccessTokenParameters() parameters.scopes = protectedAPIScopes1 accountResult?.getAccessToken(parameters: parameters, delegate: self) let message = "Retrieving access token to use with API 1..." showResultText(message) print(message) } } @IBAction func protectedApi2Pressed(_: Any) { guard let url = protectedAPIUrl2, !protectedAPIScopes2.isEmpty else { showResultText("API 2 not configured.") return } if let accessToken = accessTokenAPI2 { accessProtectedAPI(apiUrl: url, accessToken: accessToken) } else { let parameters = MSALNativeAuthGetAccessTokenParameters() parameters.scopes = protectedAPIScopes2 accountResult?.getAccessToken(parameters: parameters, delegate: self) let message = "Retrieving access token to use with API 2..." showResultText(message) print(message) } }Los métodos
protectedApi1PressedyprotectedApi2Pressedadministran el proceso de adquisición de tokens de acceso para dos conjuntos distintos de ámbitos. Primero garantizan que la dirección URL y los ámbitos de cada API estén configurados correctamente. Si ya hay disponible un token de acceso para la API, accede directamente a la API. De lo contrario, solicita un token de acceso e informa al usuario sobre el proceso de recuperación de tokens en curso.Para asignar un token de acceso a
protectedAPIScopes1yprotectedAPIScopes2, usa el siguiente fragmento de código:func onAccessTokenRetrieveCompleted(result: MSALNativeAuthTokenResult) { print("Access Token: \(result.accessToken)") if protectedAPIScopes1.allSatisfy(result.scopes.contains), let url = protectedAPIUrl1 { accessTokenAPI1 = result.accessToken accessProtectedAPI(apiUrl: url, accessToken: result.accessToken) } if protectedAPIScopes2.allSatisfy(result.scopes.contains(_:)), let url = protectedAPIUrl2 { accessTokenAPI2 = result.accessToken accessProtectedAPI(apiUrl: url, accessToken: result.accessToken) } showResultText("Signed in." + "\n\n" + "Scopes:\n\(result.scopes)" + "\n\n" + "Access Token:\n\(result.accessToken)") updateUI() } func onAccessTokenRetrieveError(error: MSAL.RetrieveAccessTokenError) { showResultText("Error retrieving access token: \(error.errorDescription ?? "No error description")") }El método
onAccessTokenRetrieveCompletedimprime el token de acceso en la consola. Luego, comprueba siprotectedAPIScopes1se incluyen en los ámbitos del resultado y siprotectedAPIUrl1está disponible; si es así, estableceaccessTokenAPI1y llama aaccessProtectedAPIcon la URL y el token. Realiza una comprobación similar deprotectedAPIScopes2yprotectedAPIUrl2, actualizandoaccessTokenAPI2y realizando la llamada API si se cumplen las condiciones. Por último, el método muestra un mensaje con el estado de inicio de sesión, los ámbitos y el token de acceso, y actualiza la IU.El método
onAccessTokenRetrieveErrormuestra un mensaje de error con la descripción del error de recuperación del token de acceso o un mensaje predeterminado si no se proporciona ninguna descripción.
Llamada a una API
Usa los fragmentos de código siguientes para llamar a una API:
func accessProtectedAPI(apiUrl: String, accessToken: String) {
guard let url = URL(string: apiUrl) else {
let errorMessage = "Invalid API url"
print(errorMessage)
DispatchQueue.main.async {
self.showResultText(errorMessage)
}
return
}
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.setValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization")
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if let error = error {
print("Error found when accessing API: \(error.localizedDescription)")
DispatchQueue.main.async {
self.showResultText(error.localizedDescription)
}
return
}
guard let httpResponse = response as? HTTPURLResponse, (200...299).contains(httpResponse.statusCode)
else {
DispatchQueue.main.async {
self.showResultText("Unsuccessful response found when accessing the API")
}
return
}
guard let data = data, let result = try? JSONSerialization.jsonObject(with: data, options: []) else {
DispatchQueue.main.async {
self.showResultText("Couldn't deserialize result JSON")
}
return
}
DispatchQueue.main.async {
self.showResultText("""
Accessed API successfully using access token.
HTTP response code: \(httpResponse.statusCode)
HTTP response body: \(result)
""")
}
}
task.resume()
}
El método accessProtectedAPI envía una solicitud GET al punto de conexión de API especificado mediante el token de acceso proporcionado. Configura la solicitud con el token en el encabezado de autorización. Cuando recibe una respuesta correcta (código de estado de HTTP 200-299), deserializa los datos JSON y actualiza la IU con el código de estado de HTTP y el cuerpo de la respuesta. Si se produce un error durante el control de solicitudes o respuestas, muestra el mensaje de error en la IU. Este método permite el acceso a la API 1 o a la API 2, según la dirección URL y el token de acceso proporcionados.