Sdílet prostřednictvím


Kurz: Přihlášení uživatelů v mobilní aplikaci pro iOS (Swift)

Toto je třetí kurz série kurzů, který vás provede přihlašováním uživatelů pomocí Microsoft Entra Externí ID.

V tomto kurzu:

  • Přihlaste se uživatele.
  • Odhlaste se od uživatele.

Požadavky

Přihlášení uživatele

Máte dvě hlavní možnosti pro přihlašování uživatelů pomocí knihovny MICROSOFT Authentication Library (MSAL) pro iOS: interaktivní nebo tiché získání tokenů.

  1. Pokud se chcete přihlásit uživatele interaktivně, použijte následující kód:

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

    Kód nejprve zkontroluje, jestli jsou k dispozici kontext aplikace a parametry webového zobrazení. Potom aktualizuje protokolování, aby indikuje, že token získává interaktivně. Dále nastaví parametry pro interaktivní získání tokenu a určí rozsahy a parametry webového zobrazení. Nastaví také typ výzvy k výběru účtu.

    Potom volá metodu acquireToken v kontextu aplikace s definovanými parametry. V obslužné rutině dokončení kontroluje případné chyby. Pokud dojde k chybě, aktualizuje protokolování chybovou zprávou. V případě úspěchu načte přístupový token z výsledku, aktualizuje protokolování pomocí tokenu a aktualizuje aktuální účet.

    Jakmile vaše aplikace získá přístupový token, můžete načíst deklarace identity přidružené k aktuálnímu účtu. K tomu použijte následující fragment kódu:

    let claims = result.account.accountClaims
    let preferredUsername = claims?["preferred_username"] as? String
    

    Kód načte deklarace identity z účtu tak, že přistupuje k accountClaims vlastnosti objektu result.account . Potom načte hodnotu deklarace identity "preferred_username" ze slovníku preferredUsername deklarací identity a přiřadí ji k proměnné.

  2. Pokud chcete uživatele přihlásit bezobslužně, použijte následující kód:

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

    Kód zahájí proces získání tokenů bezobslužně. Nejprve se pokusí načíst aktuální účet. Pokud se najde aktuální účet, získá token bezobslužně pomocí daného účtu. Pokud se nenajde žádný aktuální účet, aktualizuje protokolování tak, aby indikuje, že se nenašel žádný token, a navrhne se nejprve pokus o získání tokenu interaktivně.

    Ve výše uvedeném kódu voláme dvě funkce loadCurrentAccount a acquireTokenSilently. Funkce loadCurrentAccount by měla mít následující kód:

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

    Kód používá msAL pro iOS k načtení aktuálního účtu. Kontroluje chyby a odpovídajícím způsobem aktualizuje protokolování. Pokud se najde aktuální účet, aktualizuje ho a pokusí se získat tokeny bezobslužně. Pokud existuje předchozí účet, odhlásí se. Pokud nejsou nalezeny žádné účty, vymaže přístupový token. Nakonec provede blok dokončení, pokud je k dispozici.

    Funkce acquireTokenSilently by měla obsahovat následující kód:

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

    Tato funkce používá msAL pro iOS k tichému získání tokenu pro existující účet. Po ověření applicationContextprotokoluje proces získání tokenu. Pomocí MSALSilentTokenParametersdefinuje nezbytné parametry. Pak se pokusí získat token bezobslužně. Pokud dojde k chybám, zkontroluje požadavky na interakci uživatelů a v případě potřeby zahájí interaktivní proces. Po úspěšném dokončení aktualizuje accessToken vlastnost a protokoluje obnovený token a končí povolením tlačítka odhlásit se.

Odhlásit uživatele

Pokud se chcete odhlásit uživatele z aplikace pro iOS (Swift) pomocí KNIHOVNY MSAL pro iOS, použijte následující kód:

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

Kód ověřuje existenci applicationContext, currentAccounta webViewParamaters. Potom protokoluje proces odhlášení. Kód odebere všechny tokeny z mezipaměti pro zadaný účet. V závislosti na aktuálním režimu zařízení určuje, jestli se má odhlásit z prohlížeče. Po dokončení aktualizuje protokolovací text odpovídajícím způsobem. Pokud během procesu odhlášení dojde k chybě, zaznamená chybovou zprávu. Po úspěšném odhlášení aktualizuje přístupový token na prázdný řetězec a vymaže aktuální účet.

Další kroky

Kurz: Volání chráněného webového rozhraní API v aplikaci pro iOS (Swift)