Oktatóanyag: Felhasználók bejelentkezése és a Microsoft Graph meghívása iOS- vagy macOS-alkalmazásból

Ebben az oktatóanyagban egy olyan iOS- vagy macOS-alkalmazást hoz létre, amely integrálható a Microsoft Identitásplatform a felhasználók aláírásához és egy hozzáférési jogkivonat beszerzéséhez a Microsoft Graph API meghívásához.

Az oktatóanyag elvégzése után az alkalmazás elfogadja a személyes Microsoft-fiókok (beleértve outlook.com, live.com és mások) és a Microsoft Entra-azonosítót használó bármely cég vagy szervezet munkahelyi vagy iskolai fiókjait. Ez az oktatóanyag iOS- és macOS-alkalmazásokra is alkalmazható. Egyes lépések eltérnek a két platformtól.

Ebben az oktatóanyagban:

  • iOS- vagy macOS-alkalmazásprojekt létrehozása az Xcode-ban
  • Az alkalmazás regisztrálása a Microsoft Entra Felügyeleti központban
  • Kód hozzáadása a felhasználói bejelentkezés és kijelentkezés támogatásához
  • Kód hozzáadása a Microsoft Graph API meghívásához
  • Az alkalmazás tesztelése

Előfeltételek

Az oktatóanyag-alkalmazás működése

Screenshot of how the sample app generated by this tutorial works.

Az oktatóanyagban szereplő alkalmazás bejelentkezhet a felhasználókba, és adatokat kérhet le a Microsoft Graphtól a nevükben. Ezek az adatok egy védett API-n (ebben az esetben a Microsoft Graph API-n) keresztül érhetők el, amely engedélyezést igényel, és a Microsoft Identitásplatform védi.

Pontosabban:

  • Az alkalmazás egy böngészőn vagy a Microsoft Authenticatoron keresztül jelentkezik be a felhasználóba.
  • A végfelhasználó elfogadja az alkalmazás által kért engedélyeket.
  • Az alkalmazás hozzáférési jogkivonatot ad ki a Microsoft Graph API-hoz.
  • A hozzáférési jogkivonat szerepel a webes API-hoz irányuló HTTP-kérésben.
  • Dolgozza fel a Microsoft Graph-választ.

Ez a minta a Microsoft Authentication Library (MSAL) használatával implementálja a hitelesítést. Az MSAL automatikusan megújítja a jogkivonatokat, egyszeri bejelentkezést (SSO) biztosít az eszközön lévő többi alkalmazás között, és kezeli a fiók(ok)t.

Ha az oktatóanyagban elkészített alkalmazás egy kész verzióját szeretné letölteni, mindkét verzió megtalálható a GitHubon:

Új projekt létrehozása

  1. Nyissa meg az Xcode-ot, és válassza az Új Xcode-projekt létrehozása lehetőséget.
  2. iOS-alkalmazások esetén válassza az iOS>Egynézetes alkalmazás lehetőséget, és válassza a Tovább lehetőséget.
  3. MacOS-alkalmazások esetén válassza a macOS>Cocoa App lehetőséget, majd a Tovább gombot.
  4. Adjon meg egy terméknevet.
  5. Állítsa a Nyelvet Swiftre, és válassza a Tovább gombot.
  6. Jelöljön ki egy mappát az alkalmazás létrehozásához, és válassza a Létrehozás lehetőséget.

Az alkalmazás regisztrálása

Tipp.

A cikkben szereplő lépések a portáltól függően kissé eltérhetnek.

  1. Jelentkezzen be a Microsoft Entra felügyeleti központba legalább alkalmazásfejlesztőként.
  2. Ha több bérlőhöz is hozzáfér, a felső menü Gépház ikonjávalválthat arra a bérlőre, amelyben regisztrálni szeretné az alkalmazást a Könyvtárak + előfizetések menüből.
  3. Keresse meg az identitásalkalmazásokat>> Alkalmazásregisztrációk.
  4. Új regisztráció kiválasztása.
  5. Adja meg az alkalmazás nevét. Előfordulhat, hogy az alkalmazás felhasználói látják ezt a nevet, és később módosíthatja.
  6. A Támogatott fióktípusok területen válassza ki bármelyik szervezeti könyvtárban (Bármely Microsoft Entra-címtár – Több-bérlős) és személyes Microsoft-fiókokban (pl. Skype, Xbox) lévő fiókokat.
  7. Válassza ki a pénztárgépet.
  8. A Kezelés területen válassza a Hitelesítés>hozzáadása platform>hozzáadása iOS/macOS rendszeren lehetőséget.
  9. Adja meg a projekt csomagazonosítóját. Ha letöltötte a kódmintát, a csomag azonosítója a következő com.microsoft.identitysample.MSALiOS: . Ha saját projektet hoz létre, jelölje ki a projektet az Xcode-ban, és nyissa meg az Általános lapot. A csomagazonosító megjelenik az Identitás szakaszban.
  10. Válassza a Konfigurálás lehetőséget, és mentse az MSAL konfigurációs lapon megjelenő MSAL-konfigurációt, hogy később beírhassa azt az alkalmazás konfigurálásakor.
  11. Válassza a Kész lehetőséget.

MSAL hozzáadása

Az MSAL-kódtár alkalmazásba való telepítésének alábbi módjai közül választhat:

CocoaPods

  1. Ha CocoaPodsot használ, először hozzon MSAL létre egy podfile nevű üres fájlt a projekt .xcodeproj fájljával azonos mappában. Adja hozzá a következőket a podfile-hoz:

    use_frameworks!
    
    target '<your-target-here>' do
       pod 'MSAL'
    end
    
  2. Cserélje le <your-target-here> a projekt nevére.

  3. Egy terminálablakban keresse meg azt a mappát, amely tartalmazza a létrehozott podfájlt , és futtassa pod install az MSAL-kódtár telepítéséhez.

  4. Zárja be az Xcode-ot, és nyissa meg <your project name>.xcworkspace , hogy újra betöltse a projektet az Xcode-ban.

Carthage

Ha Carthage-t használ, telepítse MSAL a Cartfile-hoz való hozzáadásával:

github "AzureAD/microsoft-authentication-library-for-objc" "master"

Egy terminálablakban, a frissített Cartfile könyvtárban futtassa a következő parancsot, hogy a Carthage frissítse a projekt függőségeit.

Ios:

carthage update --platform iOS

macOS:

carthage update --platform macOS

Manually

Használhatja a Git Submodule-t is, vagy megtekintheti a legújabb kiadást, amelyet keretrendszerként használhat az alkalmazásban.

Az alkalmazásregisztráció hozzáadása

Ezután hozzáadjuk az alkalmazásregisztrációt a kódhoz.

Először adja hozzá a következő importálási utasítást a ViewController.swift fájl elejéhez, és adja hozzá az AppDelegate.swift vagy a SceneDelegate.swift fájlt:

import MSAL

Ezután adja hozzá a következő kódot a ViewController.swift fájlhoz, mielőtt a következőhöz: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?

Az egyetlen módosítandó érték az az érték, amely az alkalmazásazonosítóhoz van rendelvekClientID. Ez az érték azon MSAL-konfigurációs adatok része, amelyeket az oktatóanyag elején mentett az alkalmazás regisztrálásához.

Xcode-projektbeállítások konfigurálása

Adjon hozzá egy új kulcskarikacsoportot a projekt aláírási és képességeihez. A kulcskarikacsoportnak iOS-en és com.microsoft.identity.universalstorage macOS-en kell lenniecom.microsoft.adalcache.

Xcode UI displaying how the keychain group should be set up.

Csak iOS esetén konfiguráljon URL-sémákat

Ebben a lépésben regisztrálnia CFBundleURLSchemes kell, hogy a felhasználó visszakerüljön az alkalmazásba a bejelentkezés után. Emellett az LSApplicationQueriesSchemes alkalmazás a Microsoft Authenticator használatát is lehetővé teszi.

Az Xcode-ban nyissa meg az Info.plist fájlt forráskódfájlként, és adja hozzá a következőt a <dict> szakaszon belül. Cserélje le [BUNDLE_ID] a korábban használt értékre. Ha letöltötte a kódot, a csomag azonosítója a következő com.microsoft.identitysample.MSALiOS: . Ha saját projektet hoz létre, jelölje ki a projektet az Xcode-ban, és nyissa meg az Általános lapot. A csomagazonosító megjelenik az Identitás szakaszban.

<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>

Csak macOS esetén konfigurálja az App Sandboxot

  1. Lépjen az Xcode Project Gépház >Képességek lap Alkalmazás tesztkörnyezete lapjára>
  2. Jelölje be a Kimenő Csatlakozás (Ügyfél) jelölőnégyzetet.

Az alkalmazás felhasználói felületének létrehozása

Most hozzon létre egy felhasználói felületet, amely tartalmaz egy gombot a Microsoft Graph API meghívásához, egy másik kijelentkezéshez, valamint egy szöveges nézetet a kimenet megtekintéséhez, ha hozzáadja az alábbi kódot az ViewController osztályhoz:

iOS felhasználói felület

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()
}

macOS felhasználói felület


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() {}

Ezután az ViewController osztályon belül is cserélje le a metódust a viewDidLoad() következőre:

    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()
    }

MSAL használata

MSAL inicializálása

Adja hozzá a metódust az ViewControllerinitMSAL osztályhoz:

    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()
    }

Még mindig az ViewController osztályban és a initMSAL metódus után adja hozzá a metódust initWebViewParams :

iOS-kód:

func initWebViewParams() {
        self.webViewParameters = MSALWebviewParameters(authPresentationViewController: self)
    }

macOS-kód:

func initWebViewParams() {
        self.webViewParameters = MSALWebviewParameters()
    }

A bejelentkezési visszahívás kezelése (csak iOS esetén)

Nyissa meg az AppDelegate.swift fájlt. A bejelentkezés utáni visszahívás kezeléséhez adja hozzá MSALPublicClientApplication.handleMSALResponse az osztályhoz az appDelegate alábbi módon:

// 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)
}

Ha Xcode 11-et használ, az MSAL-visszahívást inkább a SceneDelegate.swiftbe kell helyeznie. Ha mind az UISceneDelegate, mind a UIApplicationDelegate támogatja a régebbi iOS-ekkel való kompatibilitást, az MSAL visszahívást mindkét fájlba kell helyezni.

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)
    }

Jogkivonatok beszerzése

Most implementálhatjuk az alkalmazás felhasználói felületének feldolgozási logikáját, és interaktívan lekérhetjük a jogkivonatokat az MSAL-on keresztül.

Az MSAL két elsődleges metódust tesz elérhetővé a jogkivonatok lekéréséhez: acquireTokenSilently() és acquireTokenInteractively().

  • acquireTokenSilently() megkísérli bejelentkezni egy felhasználót, és felhasználói beavatkozás nélkül lekérni a jogkivonatokat, amíg egy fiók jelen van. acquireTokenSilently() érvényes MSALAccount, amely az MSAL-fiók enumerálási API-jainak egyikével kérhető le. Ez az oktatóanyag az aktuális fiók lekérésére használja applicationContext.getCurrentAccount(with: msalParameters, completionBlock: {}) .

  • acquireTokenInteractively() mindig megjelenik a felhasználói felület, amikor megpróbál bejelentkezni a felhasználóba. Használhat munkamenet-cookie-kat a böngészőben vagy a Microsoft hitelesítő fiókjában, hogy interaktív egyszeri bejelentkezést biztosítson.

Adja hozzá a következő kódot az ViewController osztályhoz:

    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)
            }
        })
    }

Jogkivonat interaktív lekérése

Az alábbi kódrészlet először kap jogkivonatot egy MSALInteractiveTokenParameters objektum létrehozásával és hívásával acquireToken. Ezután a következő kódot adja hozzá:

  1. Hatókörökkel hoz létre MSALInteractiveTokenParameters .
  2. A létrehozott paraméterekkel rendelkező hívások acquireToken() .
  3. Kezeli a hibákat. További részletekért tekintse meg az iOS-hez és a macOS-hez készült MSAL hibakezelési útmutatót.
  4. Kezeli a sikeres esetet.

Adja hozzá az alábbi kódot a ViewController osztályhoz.

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()
    }
}

A promptType hitelesítés és a hozzájárulás kérésének viselkedését MSALInteractiveTokenParameters a tulajdonság konfigurálja. A következő értékek támogatottak:

  • .promptIfNecessary (alapértelmezett) – A rendszer csak akkor kéri a felhasználót, ha szükséges. Az egyszeri bejelentkezés élményét a cookie-k webnézetben való jelenléte és a fiók típusa határozza meg. Ha több felhasználó is bejelentkezett, megjelenik a fiókválasztási felület. Ez az alapértelmezett viselkedés.
  • .selectAccount – Ha nincs megadva felhasználó, a hitelesítési webnézet megjeleníti azoknak a jelenleg bejelentkezett fiókoknak a listáját, ahonnan a felhasználó választhat.
  • .login – A felhasználónak hitelesítenie kell magát a webnézetben. Ha megadja ezt az értéket, egyszerre csak egy fiók lehet bejelentkezve.
  • .consent – Megköveteli a felhasználótól, hogy járuljon hozzá a kérés hatóköreinek jelenlegi készletéhez.

Jogkivonat csendes lekérése

Ha csendesen szeretne beszerezni egy frissített jogkivonatot, adja hozzá az alábbi kódot az ViewController osztályhoz. Létrehoz egy objektumot MSALSilentTokenParameters , és meghívja a következőt 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()
        }
    }

A Microsoft Graph API meghívása

Miután rendelkezik egy jogkivonattal, az alkalmazás a HTTP-fejlécben használhatja egy engedélyezett kérést a Microsoft Graphhoz:

fejléckulcs Érték
Authorization Tulajdonosi <hozzáférési jogkivonat>

Adja hozzá a következő kódot az ViewController osztályhoz:

    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()
    }

A Microsoft Graph API-val kapcsolatos további információkért tekintse meg a Microsoft Graph API-t .

MSAL használata kijelentkezéshez

Ezután adja hozzá a kijelentkezés támogatását.

Fontos

Az MSAL használatával való kijelentkezés eltávolítja a felhasználó összes ismert információját az alkalmazásból, valamint eltávolít egy aktív munkamenetet az eszközén, ha az eszközkonfiguráció engedélyezi. Igény szerint kijelentkeztetheti a felhasználót a böngészőből.

A bejelentkezési képesség hozzáadásához adja hozzá a következő kódot az ViewController osztályon belül.

@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)
            })

        }
    }

Jogkivonat gyorsítótárazásának engedélyezése

Alapértelmezés szerint az MSAL gyorsítótárazza az alkalmazás jogkivonatait az iOS- vagy macOS-kulcskarikában.

A tokenek gyorsítótárazásának engedélyezése:

  1. Győződjön meg arról, hogy az alkalmazás megfelelően van aláírva
  2. Nyissa meg az Xcode Project Gépház >Képességek lap Kulcskarikamegosztás engedélyezése lapját>
  3. Válassza ki + és adja meg az alábbi kulcskarikacsoportok egyikét:
    • Ios: com.microsoft.adalcache
    • Macos: com.microsoft.identity.universalstorage

Segédmetenek hozzáadása

A minta elvégzéséhez adja hozzá az alábbi segédmetórát az ViewController osztályhoz.

iOS felhasználói felület:


    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)
    }

macOS felhasználói felület:

    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)
    }

Csak iOS: további eszközinformációk lekérése

A következő kóddal olvassa be az aktuális eszközkonfigurációt, beleértve azt is, hogy az eszköz megosztottként van-e konfigurálva:

    @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.")
        }
    }

Többfiókos alkalmazások

Ez az alkalmazás egyetlen fiókhoz készült. Az MSAL többfiókos forgatókönyveket is támogat, de több alkalmazásmunkát igényel. Felhasználói felületet kell létrehoznia, hogy a felhasználók kiválaszthatják, melyik fiókot szeretnék használni minden olyan művelethez, amelyhez jogkivonatokra van szükség. Másik lehetőségként az alkalmazás heurisztikus megoldást is alkalmazhat a használni kívánt fiók kiválasztásához az összes fiók MSAL-ből való lekérdezésével. Lásd például az API-t accountsFromDeviceForParameters:completionBlock:

Az alkalmazás tesztelése

Az alkalmazást egy teszteszközön vagy szimulátoron hozhatja létre és helyezheti üzembe. Be kell tudnia jelentkezni, és jogkivonatokat kell beszereznie a Microsoft Entra-azonosítóhoz vagy a személyes Microsoft-fiókokhoz.

Amikor egy felhasználó először jelentkezik be az alkalmazásba, a Microsoft identitása kérni fogja, hogy járuljon hozzá a kért engedélyekhez. Bár a felhasználók többsége képes a hozzájárulásra, egyes Microsoft Entra-bérlők letiltották a felhasználói hozzájárulást, ami megköveteli, hogy a rendszergazdák az összes felhasználó nevében hozzájárulást adjanak. A forgatókönyv támogatásához regisztrálja az alkalmazás hatóköreit.

A bejelentkezés után az alkalmazás megjeleníti a Microsoft Graph-végpontról /me visszaadott adatokat.

További lépések

Többrészes forgatókönyv-sorozatunkban további információ a védett webes API-kat hívó mobilalkalmazások készítéséről.