Включение аутентификацию в вашем приложении Swift для iOS с помощью Azure AD B2C
В этой статье показано, как добавить аутентификацию Azure Active Directory B2C (Azure AD B2C) в собственное мобильное приложение Swift для iOS. Узнайте, как интегрировать приложение Swift для iOS с Библиотекой аутентификации Майкрософт (MSAL) для iOS.
Используйте эту статью вместе с настройкой аутентификации в примере приложения Swift для iOS, заменив приложение Swift для iOS из примера своим собственным приложением Swift для iOS. После выполнения инструкций, описанных в этой статье, ваше приложение будет принимать запросы на вход через Azure AD B2C.
Предварительные требования
Ознакомьтесь с предварительными требованиями и инструкциями по интеграции в разделе Настройка проверки подлинности в образце приложения Swift для iOS с помощью Azure AD B2C.
Создание проекта приложения Swift для iOS
Если у вас еще нет приложения iOS Swift, настройте новый проект, выполнив следующие действия.
- Откройте Xcode и выберите Файл>Новый>Проект.
- Для приложений iOS выберите iOS>Приложение, а затем выберите Далее.
- В разделе Выбор параметров нового проекта укажите следующее:
-
Название продукта, например
MSALiOS
. -
Идентификатор организации, например
contoso.com
. - В качестве значения параметра Интерфейс выберите Раскадровка.
- В качестве значения параметра Жизненный цикл выберите Делегат приложения UIKit.
- В качестве значения параметра Язык выберите Swift.
-
Название продукта, например
- Выберите Далее.
- Выберите папку, в которой будет создано приложение, и нажмите Создать.
Шаг 1. Установка библиотеки MSAL
Для установки библиотеки MSAL используйте CocoaPods. В той же папке, что и XCODEPROJ-файл проекта, если файл podfile не существует, создайте пустой файл и присвойте ему имя podfile. Добавьте в файл podfile следующий код:
use_frameworks! target '<your-target-here>' do pod 'MSAL' end
Замените
<your-target-here>
на имя вашего проекта (например,MSALiOS
). Дополнительные сведения см. в справке по синтаксису Podfile.В окне терминала перейдите в папку, где находится файл podfile, и запустите pod install, чтобы установить библиотеку MSAL.
После запуска команды
pod install
будет создан файл <имя вашего проекта>.xcworkspace. Чтобы перезагрузить проект в Xcode, закройте Xcode и откройте файл <имя вашего проекта>.xcworkspace.
Шаг 2. Настройка схемы URL-адресов приложения
Когда пользователь аутентифицируется, Azure AD B2C отправляет в приложение код авторизации с помощью универсального кода ресурса (URI) перенаправления, настроенного при регистрации приложения Azure AD B2C.
Формат URI перенаправления MSAL по умолчанию — msauth.[Your_Bundle_Id]://auth
. Например, это может быть msauth.com.microsoft.identitysample.MSALiOS://auth
, где msauth.com.microsoft.identitysample.MSALiOS
— схема URL-адресов.
На этом шаге зарегистрируйте вашу схему URL-адресов с помощью массива CFBundleURLSchemes
. Приложение прослушивает схему URL-адресов для обратного вызова из Azure AD B2C.
В Xcode откройте файл Info.plist в качестве файла исходного кода. В разделе <dict>
добавьте следующий фрагмент кода XML:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>msauth.com.microsoft.identitysample.MSALiOS</string>
</array>
</dict>
</array>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>msauthv2</string>
<string>msauthv3</string>
</array>
Шаг 3. Добавление кода проверки подлинности
Пример кода создан на основе класса UIViewController
. Класс:
- Определяет структуру пользовательского интерфейса.
- Содержит сведения о поставщике удостоверений Azure AD B2C. Приложение использует эти сведения для установления отношений доверия с Azure AD B2C.
- Содержит код проверки подлинности для проверки подлинности пользователей, получает маркеры проверки подлинности и проверяет их.
Выберите, где UIViewController
пользователи проходят проверку подлинности. В UIViewController
объедините код с кодом, предоставленным в GitHub.
Шаг 4. Настройка вашего приложения Swift для iOS
Добавив код проверки подлинности, настройте приложение Swift для iOS с помощью параметров Azure AD B2C. Параметры поставщика удостоверений Azure AD B2C настраиваются в классе UIViewController
, выбранном в предыдущем разделе.
Чтобы узнать, как настроить приложение Swift для iOS, см. статью Настройка проверки подлинности в образце приложения iOS с помощью Azure AD B2C.
Шаг 5. Запуск и тестирование мобильного приложения
- Создайте и запустите проект с помощью симулятора подключенного устройства iOS.
- Выберите Войти, затем зарегистрируйтесь или войдите в систему с помощью локальной учетной записи Azure AD B2C или учетной записи социальной сети.
- После успешной аутентификации на панели навигации появится ваше отображаемое имя.
Шаг 6. Настройка составляющих блоков кода
В этом разделе описаны составляющие блоки кода, которые обеспечивают аутентификацию для приложения Swift для iOS. В нем перечислены методы UIViewController и описаны способы настройки кода.
Шаг 6.1. Создание экземпляра общедоступного клиентского приложения
Общедоступные клиентские приложения не считаются безопасными для хранения секретов приложения и не содержат секреты клиента. В viewDidLoad создайте экземпляр MSAL с помощью объекта клиентского приложения.
В следующем фрагменте кода Swift показано, как инициализировать MSAL с помощью объекта конфигурации MSALPublicClientApplicationConfig
.
Объект конфигурации содержит информацию о среде Azure AD B2C. Например, он предоставляет идентификатор клиента, URI перенаправления и полномочия для создания запросов проверки подлинности для Azure AD B2C. Сведения об объекте конфигурации см. в статье Настройка примера мобильного приложения.
do {
let signinPolicyAuthority = try self.getAuthority(forPolicy: self.kSignupOrSigninPolicy)
let editProfileAuthority = try self.getAuthority(forPolicy: self.kEditProfilePolicy)
let pcaConfig = MSALPublicClientApplicationConfig(clientId: kClientID, redirectUri: kRedirectUri, authority: signinPolicyAuthority)
pcaConfig.knownAuthorities = [signinPolicyAuthority, editProfileAuthority]
self.applicationContext = try MSALPublicClientApplication(configuration: pcaConfig)
self.initWebViewParams()
} catch {
self.updateLoggingText(text: "Unable to create application \(error)")
}
Метод initWebViewParams
настраивает интерактивную проверку подлинности.
Следующий фрагмент кода Swift инициализирует член класса webViewParameters
с системным веб-представлением. Более подробную информацию см. в статье Настройка браузеров и веб-представлений для iOS/macOS.
func initWebViewParams() {
self.webViewParameters = MSALWebviewParameters(authPresentationViewController: self)
self.webViewParameters?.webviewType = .default
}
Шаг 6.2. Запуск интерактивного запроса на авторизацию
Интерактивный запрос авторизации — это поток, в котором пользователю предлагается зарегистрироваться или войти в систему с помощью системного веб-представления. Когда пользователи нажимают кнопку Войти, вызывается метод authorizationButton
.
Метод authorizationButton
подготавливает объект MSALInteractiveTokenParameters
с использованием соответствующих данных о запросе авторизации. Метод acquireToken
использует MSALInteractiveTokenParameters
для проверки подлинности пользователей через системное веб-представление.
Следующий фрагмент кода показывает, как запустить интерактивный запрос авторизации.
let parameters = MSALInteractiveTokenParameters(scopes: kScopes, webviewParameters: self.webViewParameters!)
parameters.promptType = .selectAccount
parameters.authority = authority
applicationContext.acquireToken(with: parameters) { (result, error) in
// On error code
guard let result = result else {
self.updateLoggingText(text: "Could not acquire token: \(error ?? "No error information" as! Error)")
return
}
// On success code
self.accessToken = result.accessToken
self.updateLoggingText(text: "Access token is \(self.accessToken ?? "Empty")")
}
После того как пользователи завершат процесс авторизации (успешно или безуспешно), результат возвращается в замыкание метода acquireToken
.
Метод acquireToken
возвращает объекты result
и error
. Используйте это замыкание для выполнения следующих действий:
- обновление пользовательского интерфейса мобильного приложения путем указания сведений после завершения проверки подлинности;
- вызов службы веб-API с помощью маркера доступа;
- обработка ошибок аутентификации, например, когда пользователь отменяет поток входа.
Шаг 6.3. Вызов службы веб-API
Для вызова веб-API авторизации на основе токена приложению требуется действительный маркер доступа. Приложение выполняет следующие действия:
- получает маркер доступа с необходимыми разрешениями (областями) для конечной точки веб-API;
- Передает маркер доступа как токен носителя в заголовке авторизации HTTP-запроса, используя следующий формат:
Authorization: Bearer <access-token>
Когда пользователи проходят интерактивную авторизацию, приложение получает маркер доступа в замыкании acquireToken
. Для последующих вызовов веб-API, используйте тихий запрос токена с помощью метода acquireTokenSilent
, как описано в этом разделе.
Метод acquireTokenSilent
выполняет следующие действия:
- Пытается получить маркер доступа с запрошенными областями из кэша токенов. Токен возвращается, если он присутствует и срок его действия не истек.
- Если токен отсутствует в кэше токенов или срок его действия истек, библиотека MSAL пытается использовать маркер обновления для получения нового маркера доступа.
- Если маркер обновления не существует или срок его действия истек, возвращается исключение. В этом случае следует предложить пользователю выполнить интерактивный вход.
В следующем фрагменте кода показано, как получить маркер доступа:
do {
// Get the authority using the sign-in or sign-up user flow
let authority = try self.getAuthority(forPolicy: self.kSignupOrSigninPolicy)
// Get the current account from the application context
guard let thisAccount = try self.getAccountByPolicy(withAccounts: applicationContext.allAccounts(), policy: kSignupOrSigninPolicy) else {
self.updateLoggingText(text: "There is no account available!")
return
}
// Configure the acquire token silent parameters
let parameters = MSALSilentTokenParameters(scopes: kScopes, account:thisAccount)
parameters.authority = authority
parameters.loginHint = "username"
// Acquire token silent
self.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) {
// Start an interactive authorization code
// Notice we supply the account here. This ensures we acquire token for the same account
// as we originally authenticated.
...
}
}
self.updateLoggingText(text: "Could not acquire token: \(error)")
return
}
guard let result = result else {
self.updateLoggingText(text: "Could not acquire token: No result returned")
return
}
// On success, set the access token to the accessToken class member.
// The callGraphAPI method uses the access token to call a web API
self.accessToken = result.accessToken
...
}
} catch {
self.updateLoggingText(text: "Unable to construct parameters before calling acquire token \(error)")
}
Метод callGraphAPI
получает маркер доступа и вызывает веб-API, как показано ниже:
@objc func callGraphAPI(_ sender: UIButton) {
guard let accessToken = self.accessToken else {
self.updateLoggingText(text: "Operation failed because could not find an access token!")
return
}
let sessionConfig = URLSessionConfiguration.default
sessionConfig.timeoutIntervalForRequest = 30
let url = URL(string: self.kGraphURI)
var request = URLRequest(url: url!)
request.setValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization")
let urlSession = URLSession(configuration: sessionConfig, delegate: self, delegateQueue: OperationQueue.main)
self.updateLoggingText(text: "Calling the API....")
urlSession.dataTask(with: request) { data, response, error in
guard let validData = data else {
self.updateLoggingText(text: "Could not call API: \(error ?? "No error information" as! Error)")
return
}
let result = try? JSONSerialization.jsonObject(with: validData, options: [])
guard let validResult = result as? [String: Any] else {
self.updateLoggingText(text: "Nothing returned from API")
return
}
self.updateLoggingText(text: "API response: \(validResult.debugDescription)")
}.resume()
}
Шаг 6.4. Выход пользователей
При выходе из MSAL вся известная информация о пользователе будет удалена из приложения. Используйте метод выхода для выхода пользователей и обновления пользовательского интерфейса. Например, можно скрыть защищенные элементы пользовательского интерфейса, скрыть кнопку выхода или отобразить кнопку входа.
В следующем фрагменте кода показано, как выполнить выход пользователей:
@objc func signoutButton(_ sender: UIButton) {
do {
let thisAccount = try self.getAccountByPolicy(withAccounts: applicationContext.allAccounts(), policy: kSignupOrSigninPolicy)
if let accountToRemove = thisAccount {
try applicationContext.remove(accountToRemove)
} else {
self.updateLoggingText(text: "There is no account to signing out!")
}
...
} catch {
self.updateLoggingText(text: "Received error signing out: \(error)")
}
}
Дальнейшие действия
Вы узнаете, как выполнять следующие задачи: