Бөлісу құралы:


Руководство. Вход пользователей в мобильное приложение iOS (Swift)

Это третий учебник в серии учебников, который поможет вам выполнить вход пользователей с помощью Внешняя идентификация Microsoft Entra.

В этом руководстве вы выполните следующие действия.

  • Войдите пользователя.
  • Выйдите пользователя.

Необходимые компоненты

Вход пользователя

У вас есть два основных варианта входа пользователей с помощью библиотеки проверки подлинности Майкрософт (MSAL) для iOS: интерактивное или автоматическое получение маркеров.

  1. Для интерактивного входа в систему используйте следующий код:

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

    Код сначала проверяет, доступны ли параметры контекста приложения и веб-представления. Затем он обновляет ведение журнала, чтобы указать, что он получает маркер в интерактивном режиме. Затем он настраивает параметры для интерактивного приобретения маркеров, указывая области и параметры веб-представления. Он также задает тип запроса для выбора учетной записи.

    Затем он вызывает acquireToken метод в контексте приложения с определенными параметрами. В обработчике завершения он проверяет наличие ошибок. Если возникла ошибка, оно обновляет ведение журнала с сообщением об ошибке. При успешном выполнении он получает маркер доступа из результата, обновляет ведение журнала с помощью маркера и обновляет текущую учетную запись.

    После получения маркера доступа приложение сможет получить утверждения, связанные с текущей учетной записью. Для этого используйте следующий фрагмент кода:

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

    Код считывает утверждения из учетной записи путем accountClaims доступа к свойству result.account объекта. Затем он извлекает значение утверждения "preferred_username" из словаря утверждений и назначает его переменной preferredUsername .

  2. Чтобы автоматически войти в систему, используйте следующий код:

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

    Код инициирует процесс получения маркеров автоматически. Сначала он пытается загрузить текущую учетную запись. При обнаружении текущей учетной записи он переходит к получению маркера автоматически с помощью этой учетной записи. Если текущая учетная запись не найдена, она обновляет ведение журнала, чтобы указать, что маркер не найден и предлагает сначала получить маркер в интерактивном режиме.

    В приведенном выше коде мы вызываем две функции и loadCurrentAccount acquireTokenSilently. Функция loadCurrentAccount должна иметь следующий код:

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

    Код использует MSAL для iOS для загрузки текущей учетной записи. Он проверяет наличие ошибок и обновляет ведение журнала соответствующим образом. Если текущая учетная запись найдена, она обновляет ее и пытается автоматически получить маркеры. Если предыдущая учетная запись существует, она регистрирует выход. Если учетные записи не найдены, он очищает маркер доступа. Наконец, он выполняет блок завершения, если он указан.

    Функция acquireTokenSilently должна содержать следующий код:

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

    Эта функция использует MSAL для iOS для автоматического получения маркера для существующей учетной записи. После проверки applicationContextон регистрирует процесс приобретения маркера. С помощью MSALSilentTokenParametersон определяет необходимые параметры. Затем он пытается получить маркер автоматически. Если возникают ошибки, он проверяет требования взаимодействия с пользователем, инициируя интерактивный процесс при необходимости. После успешного выполнения он обновляет accessToken свойство и регистрирует обновленный маркер, завершив включение кнопки выхода.

Выход пользователя

Чтобы вывести пользователя из приложения iOS (Swift) с помощью MSAL для iOS, используйте следующий код:

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

Код проверяет существование applicationContextобъекта , currentAccountи webViewParamaters. Затем он регистрирует процесс выхода. Код удаляет все маркеры из кэша для предоставленной учетной записи. В зависимости от текущего режима устройства определяется, следует ли выйти из браузера. По завершении он обновляет текст ведения журнала соответствующим образом. Если во время процесса выхода возникает ошибка, он регистрирует сообщение об ошибке. После успешного выхода он обновляет маркер доступа до пустой строки и очищает текущую учетную запись.

Следующие шаги

Руководство. Вызов защищенного веб-API в приложении iOS (Swift).