Tutorial: Masuk pengguna dan memanggil Microsoft Graph dari aplikasi iOS atau macOS
Dalam tutorial ini, Anda membuat aplikasi iOS atau macOS yang terintegrasi dengan platform identitas Microsoft untuk menandatangani pengguna dan mendapatkan token akses untuk memanggil Microsoft Graph API.
Setelah menyelesaikan tutorial, aplikasi Anda menerima rincian masuk akun Microsoft pribadi (termasuk outlook.com, live.com, dan lainnya) dan akun kantor atau sekolah dari perusahaan atau organisasi mana pun yang menggunakan ID Microsoft Entra. Tutorial ini berlaku untuk aplikasi iOS dan macOS. Beberapa langkah berbeda antara kedua platform.
Dalam tutorial ini:
- Membuat proyek app iOS atau macOS di Xcode
- Mendaftarkan aplikasi di pusat admin Microsoft Entra
- Menambahkan kode untuk mendukung upaya masuk dan keluar pengguna
- Menambahkan kode untuk memanggil Microsoft Graph API
- Menguji aplikasi
Prasyarat
Cara kerja aplikasi tutorial
Aplikasi dalam tutorial ini dapat memasukkan pengguna dan mendapatkan data dari Microsoft Graph atas nama mereka. Data ini diakses melalui API yang dilindungi (Microsoft Graph API dalam hal ini) yang memerlukan otorisasi dan dilindungi oleh platform identitas Microsoft.
Lebih spesifik:
- Aplikasi Anda masuk ke pengguna baik melalui browser atau Microsoft Authenticator.
- Pengguna akhir menerima izin yang diminta aplikasi Anda.
- Aplikasi Anda mengeluarkan token akses untuk Microsoft Graph API.
- Token akses disertakan dalam permintaan HTTP ke API web.
- Memproses respons Microsoft Graph.
Sampel ini menggunakan Pustaka Autentikasi Microsoft (MSAL) untuk menerapkan Autentikasi. MSAL akan memperbarui token secara otomatis, memberikan akses menyeluruh (SSO) antara aplikasi lain di perangkat, dan mengelola akun.
Jika ingin mengunduh versi lengkap aplikasi yang Anda buat dalam tutorial ini, Anda dapat menemukan kedua versi di GitHub:
- Sampel kode iOS (GitHub)
- Sampel kode macOS (GitHub)
Membuat proyek baru
- Buka Xcode dan pilih Buat proyek Xcode baru.
- Untuk aplikasi iOS, pilih iOS>Aplikasi tampilan tunggal, lalu pilih Berikutnya.
- Untuk aplikasi macOS, pilih MacOS>Aplikasi Cocoa, lalu pilih Berikutnya.
- Memberikan nama produk.
- Atur Bahasa ke Swift dan pilih Berikutnya.
- Pilih folder untuk membuat aplikasi Anda, lalu pilih Buat.
Mendaftarkan aplikasi
Tip
Langkah-langkah dalam artikel ini mungkin sedikit berbeda berdasarkan portal tempat Anda memulai.
- Masuk ke pusat admin Microsoft Entra setidaknya sebagai Pengembang Aplikasi.
- Jika Anda memiliki akses ke beberapa penyewa, gunakan ikon Pengaturan di menu atas untuk beralih ke penyewa tempat Anda ingin mendaftarkan aplikasi dari menu Direktori + langganan.
- Telusuri Aplikasi >Identitas>Pendaftaran aplikasi.
- Pilih Pendaftaran baru.
- Masukkan Nama untuk aplikasi Anda. Pengguna aplikasi mungkin melihat nama ini, dan Anda dapat mengubahnya nanti.
- Pilih Akun di direktori organisasi apa pun (Direktori Microsoft Entra apa pun - Multipenyewa) dan akun Microsoft pribadi (misalnya Skype, Xbox) di bawah Jenis akun yang didukung.
- Pilih Daftarkan.
- Di bawah Kelola, pilih Autentikasi>Tambahkan platform>iOS/macOS.
- Memasukkan ID Bundle proyek Anda. Jika sudah mengunduh sampel kode, ID Bundel adalah
com.microsoft.identitysample.MSALiOS
. Jika membuat proyek Anda sendiri, pilih proyek Anda di Xcode dan buka tab Umum. Pengidentifikasi bundel akan muncul di bagian Identitas. - Pilih Konfigurasi dan simpan Konfigurasi MSAL yang muncul di halaman Konfigurasi MSAL, sehingga Anda dapat memasukkannya saat mengonfigurasi aplikasi nanti.
- Pilih Selesai.
Menambahkan MSAL
Pilih salah satu cara berikut untuk menginstal pustaka MSAL di aplikasi Anda:
CocoaPods
Jika Anda menggunakan CocoaPods, instal
MSAL
dengan membuat file kosong yang disebut terlebih dahulu di folder yang sama dengan file proyek Anda. Tambahkan yang berikut ke Podfile:use_frameworks! target '<your-target-here>' do pod 'MSAL' end
Ganti
<your-target-here>
dengan nama proyek Anda.Di jendela terminal, navigasi ke folder yang berisi podfile yang Anda buat dan jalankan
pod install
untuk menginstal pustaka MSAL.Tutup Xcode dan buka
<your project name>.xcworkspace
untuk memuat ulang proyek di Xcode.
Carthage
Jika Anda menggunakan Carthage, instal MSAL
dengan menambahkannya ke Cartfile:
github "AzureAD/microsoft-authentication-library-for-objc" "master"
Dari jendela terminal, dalam direktori yang sama dengan Cartfile yang diperbarui, jalankan perintah berikut agar Carthage memperbarui dependensi dalam proyek Anda.
iOS:
carthage update --platform iOS
macOS:
carthage update --platform macOS
Secara manual…
Anda juga dapat menggunakan Git Submodule, atau melihat rilis terbaru untuk digunakan sebagai kerangka kerja dalam aplikasi Anda.
Menambahkan pendaftaran aplikasi
Selanjutnya, kami menambahkan pendaftaran aplikasi Anda ke kode Anda.
Pertama, tambahkan pernyataan impor berikut ke bagian atas file ViewController.swift dan AppDelegate.swift atau SceneDelegate.swift:
import MSAL
Selanjutnya, tambahkan kode berikut ke ViewController.swift sebelum ke viewDidLoad()
:
// Update the below to your client ID. The below is for running the demo only
let kClientID = "Your_Application_Id_Here"
let kGraphEndpoint = "https://graph.microsoft.com/" // the Microsoft Graph endpoint
let kAuthority = "https://login.microsoftonline.com/common" // this authority allows a personal Microsoft account and a work or school account in any organization's Azure AD tenant to sign in
let kScopes: [String] = ["user.read"] // request permission to read the profile of the signed-in user
var accessToken = String()
var applicationContext : MSALPublicClientApplication?
var webViewParameters : MSALWebviewParameters?
var currentAccount: MSALAccount?
Satu-satunya nilai yang Anda ubah adalah nilai yang ditetapkan untuk kClientID
menjadi ID Aplikasi Anda. Nilai ini adalah bagian dari data Konfigurasi MSAL yang Anda simpan selama langkah di awal tutorial ini untuk mendaftarkan aplikasi.
Mengonfigurasi pengaturan proyek Xcode
Tambahkan grup rantai kunci baru ke proyek Penandatanganan & Kemampuan. Grup rantai kunci harus berupa com.microsoft.adalcache
di iOS dan com.microsoft.identity.universalstorage
di macOS.
Khusus untuk iOS, konfigurasikan skema URL
Dalam langkah ini, Anda akan mendaftarkan CFBundleURLSchemes
sehingga pengguna dapat diarahkan kembali ke aplikasi setelah masuk. Omong-omong, LSApplicationQueriesSchemes
juga memungkinkan aplikasi Anda menggunakan Microsoft Authenticator.
Di Xcode, buka Info.plist sebagai file kode sumber, dan tambahkan hal berikut di dalam bagian <dict>
. Ganti [BUNDLE_ID]
dengan nilai yang sebelumnya Anda gunakan. Jika Anda mengunduh kode, pengidentifikasi bundel adalah com.microsoft.identitysample.MSALiOS
. Jika membuat proyek Anda sendiri, pilih proyek Anda di Xcode dan buka tab Umum. Pengidentifikasi bundel akan muncul di bagian Identitas.
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>msauth.[BUNDLE_ID]</string>
</array>
</dict>
</array>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>msauthv2</string>
<string>msauthv3</string>
</array>
Khusus untuk macOS, konfigurasikan Kotak Pasir Aplikasi
- Buka Pengaturan Proyek Xcode Anda >tab Kemampuan>Kotak Pasir Aplikasi
- Centang kotak Koneksi Keluar (Klien).
Membuat antarmuka pengguna aplikasi
Sekarang, buat antarmuka pengguna yang menyertakan tombol untuk memanggil Microsoft Graph API, buat yang lain untuk keluar, dan tampilan teks untuk melihat beberapa output dengan menambahkan kode berikut ke kelas ViewController
:
Antarmuka pengguna iOS
var loggingText: UITextView!
var signOutButton: UIButton!
var callGraphButton: UIButton!
var usernameLabel: UILabel!
func initUI() {
usernameLabel = UILabel()
usernameLabel.translatesAutoresizingMaskIntoConstraints = false
usernameLabel.text = ""
usernameLabel.textColor = .darkGray
usernameLabel.textAlignment = .right
self.view.addSubview(usernameLabel)
usernameLabel.topAnchor.constraint(equalTo: view.topAnchor, constant: 50.0).isActive = true
usernameLabel.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -10.0).isActive = true
usernameLabel.widthAnchor.constraint(equalToConstant: 300.0).isActive = true
usernameLabel.heightAnchor.constraint(equalToConstant: 50.0).isActive = true
// Add call Graph button
callGraphButton = UIButton()
callGraphButton.translatesAutoresizingMaskIntoConstraints = false
callGraphButton.setTitle("Call Microsoft Graph API", for: .normal)
callGraphButton.setTitleColor(.blue, for: .normal)
callGraphButton.addTarget(self, action: #selector(callGraphAPI(_:)), for: .touchUpInside)
self.view.addSubview(callGraphButton)
callGraphButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
callGraphButton.topAnchor.constraint(equalTo: view.topAnchor, constant: 120.0).isActive = true
callGraphButton.widthAnchor.constraint(equalToConstant: 300.0).isActive = true
callGraphButton.heightAnchor.constraint(equalToConstant: 50.0).isActive = true
// Add sign out button
signOutButton = UIButton()
signOutButton.translatesAutoresizingMaskIntoConstraints = false
signOutButton.setTitle("Sign Out", for: .normal)
signOutButton.setTitleColor(.blue, for: .normal)
signOutButton.setTitleColor(.gray, for: .disabled)
signOutButton.addTarget(self, action: #selector(signOut(_:)), for: .touchUpInside)
self.view.addSubview(signOutButton)
signOutButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
signOutButton.topAnchor.constraint(equalTo: callGraphButton.bottomAnchor, constant: 10.0).isActive = true
signOutButton.widthAnchor.constraint(equalToConstant: 150.0).isActive = true
signOutButton.heightAnchor.constraint(equalToConstant: 50.0).isActive = true
let deviceModeButton = UIButton()
deviceModeButton.translatesAutoresizingMaskIntoConstraints = false
deviceModeButton.setTitle("Get device info", for: .normal);
deviceModeButton.setTitleColor(.blue, for: .normal);
deviceModeButton.addTarget(self, action: #selector(getDeviceMode(_:)), for: .touchUpInside)
self.view.addSubview(deviceModeButton)
deviceModeButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
deviceModeButton.topAnchor.constraint(equalTo: signOutButton.bottomAnchor, constant: 10.0).isActive = true
deviceModeButton.widthAnchor.constraint(equalToConstant: 150.0).isActive = true
deviceModeButton.heightAnchor.constraint(equalToConstant: 50.0).isActive = true
// Add logging textfield
loggingText = UITextView()
loggingText.isUserInteractionEnabled = false
loggingText.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(loggingText)
loggingText.topAnchor.constraint(equalTo: deviceModeButton.bottomAnchor, constant: 10.0).isActive = true
loggingText.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: 10.0).isActive = true
loggingText.rightAnchor.constraint(equalTo: self.view.rightAnchor, constant: -10.0).isActive = true
loggingText.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: 10.0).isActive = true
}
func platformViewDidLoadSetup() {
NotificationCenter.default.addObserver(self,
selector: #selector(appCameToForeGround(notification:)),
name: UIApplication.willEnterForegroundNotification,
object: nil)
}
@objc func appCameToForeGround(notification: Notification) {
self.loadCurrentAccount()
}
Antarmuka pengguna macOS
var callGraphButton: NSButton!
var loggingText: NSTextView!
var signOutButton: NSButton!
var usernameLabel: NSTextField!
func initUI() {
usernameLabel = NSTextField()
usernameLabel.translatesAutoresizingMaskIntoConstraints = false
usernameLabel.stringValue = ""
usernameLabel.isEditable = false
usernameLabel.isBezeled = false
self.view.addSubview(usernameLabel)
usernameLabel.topAnchor.constraint(equalTo: view.topAnchor, constant: 30.0).isActive = true
usernameLabel.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -10.0).isActive = true
// Add call Graph button
callGraphButton = NSButton()
callGraphButton.translatesAutoresizingMaskIntoConstraints = false
callGraphButton.title = "Call Microsoft Graph API"
callGraphButton.target = self
callGraphButton.action = #selector(callGraphAPI(_:))
callGraphButton.bezelStyle = .rounded
self.view.addSubview(callGraphButton)
callGraphButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
callGraphButton.topAnchor.constraint(equalTo: view.topAnchor, constant: 50.0).isActive = true
callGraphButton.heightAnchor.constraint(equalToConstant: 34.0).isActive = true
// Add sign out button
signOutButton = NSButton()
signOutButton.translatesAutoresizingMaskIntoConstraints = false
signOutButton.title = "Sign Out"
signOutButton.target = self
signOutButton.action = #selector(signOut(_:))
signOutButton.bezelStyle = .texturedRounded
self.view.addSubview(signOutButton)
signOutButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
signOutButton.topAnchor.constraint(equalTo: callGraphButton.bottomAnchor, constant: 10.0).isActive = true
signOutButton.heightAnchor.constraint(equalToConstant: 34.0).isActive = true
signOutButton.isEnabled = false
// Add logging textfield
loggingText = NSTextView()
loggingText.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(loggingText)
loggingText.topAnchor.constraint(equalTo: signOutButton.bottomAnchor, constant: 10.0).isActive = true
loggingText.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: 10.0).isActive = true
loggingText.rightAnchor.constraint(equalTo: self.view.rightAnchor, constant: -10.0).isActive = true
loggingText.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -10.0).isActive = true
loggingText.widthAnchor.constraint(equalToConstant: 500.0).isActive = true
loggingText.heightAnchor.constraint(equalToConstant: 300.0).isActive = true
}
func platformViewDidLoadSetup() {}
Selanjutnya, juga di dalam kelas ViewController
, ganti metode viewDidLoad()
dengan:
override func viewDidLoad() {
super.viewDidLoad()
initUI()
do {
try self.initMSAL()
} catch let error {
self.updateLogging(text: "Unable to create Application Context \(error)")
}
self.loadCurrentAccount()
self.platformViewDidLoadSetup()
}
Menggunakan MSAL
Menginisialisasi MSAL
Ke kelas ViewController
, tambahkan metode initMSAL
:
func initMSAL() throws {
guard let authorityURL = URL(string: kAuthority) else {
self.updateLogging(text: "Unable to create authority URL")
return
}
let authority = try MSALAADAuthority(url: authorityURL)
let msalConfiguration = MSALPublicClientApplicationConfig(clientId: kClientID, redirectUri: nil, authority: authority)
self.applicationContext = try MSALPublicClientApplication(configuration: msalConfiguration)
self.initWebViewParams()
}
Masih di ViewController
kelas dan setelah metode initMSAL
, tambahkan metode initWebViewParams
:
Kode iOS:
func initWebViewParams() {
self.webViewParameters = MSALWebviewParameters(authPresentationViewController: self)
}
Kode macOS:
func initWebViewParams() {
self.webViewParameters = MSALWebviewParameters()
}
Menangani panggilan balik kredensial masuk (khusus iOS)
Open file AppDelegate.swift. Untuk menangani panggilan balik setelah masuk, tambahkan MSALPublicClientApplication.handleMSALResponse
ke kelas appDelegate
seperti ini:
// Inside AppDelegate...
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
return MSALPublicClientApplication.handleMSALResponse(url, sourceApplication: options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String)
}
Jika menggunakan Xcode 11, Anda harus melakukan panggilan balik MSAL ke dalam file SceneDelegate.swift sebagai gantinya. Jika Anda mendukung UISceneDelegate dan UIApplicationDelegate untuk kompatibilitas dengan iOS yang lebih lama, panggilan balik MSAL harus ditempatkan ke dalam kedua file.
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
guard let urlContext = URLContexts.first else {
return
}
let url = urlContext.url
let sourceApp = urlContext.options.sourceApplication
MSALPublicClientApplication.handleMSALResponse(url, sourceApplication: sourceApp)
}
Mendapatkan Token
Sekarang, kami dapat menerapkan logika pemrosesan antarmuka pengguna aplikasi dan mendapatkan token secara interaktif melalui MSAL.
MSAL mengekspos dua metode utama untuk mendapatkan token: acquireTokenSilently()
dan acquireTokenInteractively()
.
acquireTokenSilently()
berupaya memasukkan pengguna dan mendapatkan token tanpa interaksi pengguna selama akun tersedia.acquireTokenSilently()
memerlukan , yang validMSALAccount
yang dapat diambil dengan menggunakan salah satu API enumerasi akun MSAL. Tutorial ini menggunakanapplicationContext.getCurrentAccount(with: msalParameters, completionBlock: {})
untuk mengambil akun saat ini.acquireTokenInteractively()
selalu menampilkan antarmuka pengguna ketika mencoba untuk memasukkan pengguna. Ini dapat menggunakan cookie sesi di browser atau akun di pengautentikasi Microsoft untuk memberikan pengalaman interaktif-SSO.
Tambahkan kode berikut ke kelas ViewController
:
func getGraphEndpoint() -> String {
return kGraphEndpoint.hasSuffix("/") ? (kGraphEndpoint + "v1.0/me/") : (kGraphEndpoint + "/v1.0/me/");
}
@objc func callGraphAPI(_ sender: AnyObject) {
self.loadCurrentAccount { (account) in
guard let currentAccount = account else {
// We check to see if we have a current logged in account.
// If we don't, then we need to sign someone in.
self.acquireTokenInteractively()
return
}
self.acquireTokenSilently(currentAccount)
}
}
typealias AccountCompletion = (MSALAccount?) -> Void
func loadCurrentAccount(completion: AccountCompletion? = nil) {
guard let applicationContext = self.applicationContext else { return }
let msalParameters = MSALParameters()
msalParameters.completionBlockQueue = DispatchQueue.main
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.updateLogging(text: "Found a signed in account \(String(describing: currentAccount.username)). Updating data for that account...")
self.updateCurrentAccount(account: currentAccount)
if let completion = completion {
completion(self.currentAccount)
}
return
}
self.updateLogging(text: "Account signed out. Updating UX")
self.accessToken = ""
self.updateCurrentAccount(account: nil)
if let completion = completion {
completion(nil)
}
})
}
Mendapatkan token secara interaktif
Cuplikan kode berikut mendapatkan token untuk pertama kalinya dengan membuat objek MSALInteractiveTokenParameters
dan memanggil acquireToken
. Selanjutnya Anda menambahkan kode yang:
- Membuat
MSALInteractiveTokenParameters
dengan cakupan. - Memanggil
acquireToken()
dengan parameter yang dibuat. - Menangani kesalahan. Untuk detail selengkapnya, lihat panduan penanganan kesalahan MSAL untuk iOS dan macOS.
- Menangani kasus yang berhasil.
Tambahkan kode berikut ke kelas ViewController
.
func acquireTokenInteractively() {
guard let applicationContext = self.applicationContext else { return }
guard let webViewParameters = self.webViewParameters else { return }
// #1
let parameters = MSALInteractiveTokenParameters(scopes: kScopes, webviewParameters: webViewParameters)
parameters.promptType = .selectAccount
// #2
applicationContext.acquireToken(with: parameters) { (result, error) in
// #3
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
}
// #4
self.accessToken = result.accessToken
self.updateLogging(text: "Access token is \(self.accessToken)")
self.updateCurrentAccount(account: result.account)
self.getContentWithToken()
}
}
Properti promptType
dari MSALInteractiveTokenParameters
mengonfigurasi autentikasi dan perilaku permintaan persetujuan. Nilai berikut ini didukung:
.promptIfNecessary
(default) - Pengguna hanya diminta jika perlu. Pengalaman SSO ditentukan oleh kehadiran cookie di tampilan web, dan jenis akun. Jika beberapa pengguna masuk, pengalaman pemilihan akun akan diberikan. Ini adalah perilaku default..selectAccount
- Jika tidak ada pengguna yang ditentukan, tampilan web autentikasi memberikan daftar akun yang saat ini masuk untuk dipilih pengguna..login
- Mengharuskan pengguna untuk mengautentikasi di tampilan web. Hanya satu akun yang dapat masuk pada satu waktu jika Anda menentukan nilai ini..consent
- Mengharuskan pengguna untuk menyetujui serangkaian cakupan saat ini untuk permintaan.
Mendapatkan token secara diam-diam
Untuk memperoleh token yang diperbarui secara diam-diam, tambahkan kode berikut ke kelas ViewController
. Tindakan ini akan membuat objek MSALSilentTokenParameters
dan memanggil acquireTokenSilent()
:
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.
*/
let parameters = MSALSilentTokenParameters(scopes: 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)
self.getContentWithToken()
}
}
Menghubungi Microsoft Graph API
Setelah mendapatkan token, aplikasi Anda dapat menggunakannya di header HTTP untuk membuat permintaan resmi ke Microsoft Graph:
tombol header | value |
---|---|
Otorisasi | <Token akses> pembawa |
Tambahkan kode berikut ke kelas ViewController
:
func getContentWithToken() {
// Specify the Graph API endpoint
let graphURI = getGraphEndpoint()
let url = URL(string: graphURI)
var request = URLRequest(url: url!)
// Set the Authorization header for the request. We use Bearer tokens, so we specify Bearer + the token we got from the result
request.setValue("Bearer \(self.accessToken)", forHTTPHeaderField: "Authorization")
URLSession.shared.dataTask(with: request) { data, response, error in
if let error = error {
self.updateLogging(text: "Couldn't get graph result: \(error)")
return
}
guard let result = try? JSONSerialization.jsonObject(with: data!, options: []) else {
self.updateLogging(text: "Couldn't deserialize result JSON")
return
}
self.updateLogging(text: "Result from Graph: \(result))")
}.resume()
}
Lihat Microsoft Graph API untuk mempelajari selengkapnya tentang Microsoft Graph API.
Menggunakan MSAL untuk Keluar
Selanjutnya, tambahkan dukungan untuk keluar.
Penting
Keluar dengan MSAL menghapus semua informasi yang diketahui tentang pengguna dari aplikasi, serta menghapus sesi aktif di perangkat mereka ketika diizinkan oleh konfigurasi perangkat. Anda juga dapat secara opsional menandatangani pengguna dari browser.
Untuk menambahkan kemampuan keluar, tambahkan kode berikut di dalam kelas ViewController
.
@objc func signOut(_ sender: AnyObject) {
guard let applicationContext = self.applicationContext else { return }
guard let account = self.currentAccount else { return }
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: self.webViewParameters!)
signoutParameters.signoutFromBrowser = false // set this to true if you also want to signout from browser or webview
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)
})
}
}
Mengaktifkan penembolokan token
Secara default, MSAL membuat cache token aplikasi Anda di rantai kunci iOS atau macOS.
Untuk mengaktifkan penembolokan token:
- Pastikan aplikasi Anda ditandatangani dengan benar
- Buka Pengaturan Proyek Xcode Anda >tab Kemampuan>Aktifkan Berbagi Rantai Kunci
- Pilih + dan masukkan salah satu Grup Rantai Kunci berikut:
- iOS:
com.microsoft.adalcache
- macOS:
com.microsoft.identity.universalstorage
- iOS:
Menambahkan metode pendukung
Tambahkan metode pendukung berikut ke kelas ViewController
untuk menyelesaikan sampel.
Antarmuka pengguna iOS:
func updateLogging(text : String) {
if Thread.isMainThread {
self.loggingText.text = text
} else {
DispatchQueue.main.async {
self.loggingText.text = text
}
}
}
func updateSignOutButton(enabled : Bool) {
if Thread.isMainThread {
self.signOutButton.isEnabled = enabled
} else {
DispatchQueue.main.async {
self.signOutButton.isEnabled = enabled
}
}
}
func updateAccountLabel() {
guard let currentAccount = self.currentAccount else {
self.usernameLabel.text = "Signed out"
return
}
self.usernameLabel.text = currentAccount.username
}
func updateCurrentAccount(account: MSALAccount?) {
self.currentAccount = account
self.updateAccountLabel()
self.updateSignOutButton(enabled: account != nil)
}
Antarmuka pengguna macOS:
func updateLogging(text : String) {
if Thread.isMainThread {
self.loggingText.string = text
} else {
DispatchQueue.main.async {
self.loggingText.string = text
}
}
}
func updateSignOutButton(enabled : Bool) {
if Thread.isMainThread {
self.signOutButton.isEnabled = enabled
} else {
DispatchQueue.main.async {
self.signOutButton.isEnabled = enabled
}
}
}
func updateAccountLabel() {
guard let currentAccount = self.currentAccount else {
self.usernameLabel.stringValue = "Signed out"
return
}
self.usernameLabel.stringValue = currentAccount.username ?? ""
self.usernameLabel.sizeToFit()
}
func updateCurrentAccount(account: MSALAccount?) {
self.currentAccount = account
self.updateAccountLabel()
self.updateSignOutButton(enabled: account != nil)
}
Hanya untuk iOS: dapatkan informasi perangkat tambahan
Gunakan kode berikut untuk membaca konfigurasi perangkat saat ini, termasuk apakah perangkat dikonfigurasi sebagai dibagikan:
@objc func getDeviceMode(_ sender: AnyObject) {
if #available(iOS 13.0, *) {
self.applicationContext?.getDeviceInformation(with: nil, completionBlock: { (deviceInformation, error) in
guard let deviceInfo = deviceInformation else {
self.updateLogging(text: "Device info not returned. Error: \(String(describing: error))")
return
}
let isSharedDevice = deviceInfo.deviceMode == .shared
let modeString = isSharedDevice ? "shared" : "private"
self.updateLogging(text: "Received device info. Device is in the \(modeString) mode.")
})
} else {
self.updateLogging(text: "Running on older iOS. GetDeviceInformation API is unavailable.")
}
}
Aplikasi multi-akun
Aplikasi ini dibuat untuk skenario satu akun. MSAL juga mendukung skenario multi-akun, tetapi membutuhkan lebih banyak pekerjaan aplikasi. Anda perlu membuat UI untuk membantu pengguna memilih akun mana yang ingin mereka gunakan untuk setiap tindakan yang memerlukan token. Atau, aplikasi Anda dapat menerapkan heuristik untuk memilih akun mana yang akan digunakan dengan mengkueri semua akun dari MSAL. Misalnya, lihat accountsFromDeviceForParameters:completionBlock:
API
Menguji aplikasi Anda
Buat dan sebarkan aplikasi ke perangkat pengujian atau simulator. Anda harus dapat masuk dan mendapatkan token untuk ID Microsoft Entra atau akun Microsoft pribadi.
Pertama kali pengguna masuk ke aplikasi Anda, mereka akan diminta oleh identitas Microsoft untuk menyetujui izin yang diminta. Meskipun sebagian besar pengguna mampu menyetujui, beberapa penyewa Microsoft Entra telah menonaktifkan persetujuan pengguna, yang mengharuskan admin untuk menyetujui atas nama semua pengguna. Untuk mendukung skenario ini, daftarkan cakupan aplikasi Anda.
Setelah masuk, aplikasi akan menampilkan data yang dikembalikan dari titik akhir /me
Microsoft Graph.
Langkah berikutnya
Pelajari selengkapnya tentang cara membangun aplikasi seluler yang memanggil API web yang dilindungi dalam seri skenario multi-bagian kami.