Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Si applica a:
Tenant esterni (altre informazioni)
Questa esercitazione illustra come acquisire un token di accesso e chiamare un'API nell'app iOS/macOS. Microsoft Authentication Library (MSAL) native authentication SDK per iOS/macOS consente di acquisire più token di accesso con un single sign-in. Questa funzionalità consente di acquisire uno o più token di accesso senza richiedere a un utente di ripetere l'autenticazione.
In questa esercitazione, farai:
- Acquisire uno o più token di accesso.
- Chiamare un'API
Prerequisiti
- Completare i passaggi descritti in Accedere agli utenti e chiamare un'API nell'app per dispositivi mobili iOS di esempio usando l'autenticazione nativa.
- Completare i passaggi descritti in Esercitazione: Aggiungere l'accesso e disconnettersi nell'app iOS/macOS usando l'autenticazione nativa. Questa esercitazione illustra come accedere agli utenti nell'app iOS/macOS usando l'autenticazione nativa.
Acquisire uno o più token di accesso
MSAL native authentication SDK può archiviare più token di accesso. Dopo l'accesso, è possibile ottenere un token di accesso usando la funzione getAccessToken(parameters:) e specificando gli ambiti per il nuovo token di accesso che si vuole concedere.
Dichiarare e impostare i valori per un set di ambiti API usando il frammento di codice seguente:
let protectedAPIUrl1: String? = nil let protectedAPIUrl2: String? = nil let protectedAPIScopes1: [String] = [] let protectedAPIScopes2: [String] = [] var accessTokenAPI1: String? var accessTokenAPI2: String?- Inizializzare
protectedAPIUrl1con l'URL della prima API Web. - Inizializza
protectedAPIUrl2con l'URL della seconda API Web. - Definire
protectedAPIScopes1con ambiti per la prima API, ad esempio["api://<Resource_App_ID>/ToDoList.Read", "api://<Resource_App_ID>/ToDoList.ReadWrite"]. - Definire
protectedAPIScopes2con ambiti per la seconda API, in modo simile aprotectedAPIScopes1. - Dichiara le variabili stringa facoltative
accessTokenAPI1eaccessTokenAPI2.
- Inizializzare
Effettua l'accesso come utente utilizzando il frammento di codice seguente:
@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) }Il metodo
signInPressedgestisce la pressione del pulsante di accesso. Controlla se i campi di posta elettronica e password sono compilati. Se uno dei due è vuoto, viene visualizzato il messaggio di posta elettronica o la password non impostata. Se entrambi i campi vengono compilati, registra il messaggio di posta elettronica, visualizza "Accesso..." e avvia l'accesso usando il metodosignIndanativeAuthcon il messaggio di posta elettronica e la password specificati. L'SDK recupera un token valido per gli ambiti OIDC predefiniti (openid, offline_access, profile) perché non vengono specificati ambiti.Acquisire uno o più token di accesso usando il frammento di codice seguente:
@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) } }I metodi
protectedApi1PressedeprotectedApi2Pressedgestiscono il processo di acquisizione dei token di accesso per due set distinti di ambiti. Prima di tutto assicurano che l'URL e gli ambiti di ogni API siano configurati correttamente. Se è già disponibile un token di accesso per l'API, accede direttamente all'API. In caso contrario, richiede un token di accesso e informa l'utente del processo di recupero dei token in corso.Per assegnare un token di accesso a
protectedAPIScopes1eprotectedAPIScopes2, usare il frammento di codice seguente: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")") }Il metodo
onAccessTokenRetrieveCompletedstampa il token di accesso nella console. Controlla quindi seprotectedAPIScopes1sono inclusi negli ambiti del risultato e seprotectedAPIUrl1è disponibile; in tal caso, impostaaccessTokenAPI1e chiamaaccessProtectedAPIcon l'URL e il token. Esegue un controllo simile perprotectedAPIScopes2eprotectedAPIUrl2, aggiornandoaccessTokenAPI2e effettuando la chiamata API se vengono soddisfatte le condizioni. Infine, il metodo visualizza un messaggio con lo stato, gli ambiti e il token di accesso connessi e aggiorna l'interfaccia utente.Il metodo
onAccessTokenRetrieveErrorvisualizza un messaggio di errore con la descrizione dell'errore di recupero del token di accesso o un messaggio predefinito se non viene fornita alcuna descrizione.
Chiamare un'API
Usare i frammenti di codice seguenti per chiamare un'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()
}
Il metodo accessProtectedAPI invia una richiesta GET all'endpoint API specificato usando il token di accesso fornito. Configura la richiesta con il token nell'intestazione Autorizzazione. Quando riceve una risposta corretta (codice di stato HTTP 200-299), deserializza i dati JSON e aggiorna l'interfaccia utente con il codice di stato HTTP e il corpo della risposta. Se si verifica un errore durante la gestione della richiesta o della risposta, viene visualizzato il messaggio di errore nell'interfaccia utente. Questo metodo consente l'accesso all'API 1 o all'API 2, a seconda dell'URL e del token di accesso forniti.