Как SFAuthenticationSession хранит связанные с сеансом куки в Safari

Тл ; др прочитал последний абзац.

Я использую библиотеку AppAuth ( https://github.com/openid/AppAuth-iOS) для обработки аутентификации пользователей на основе OpenID, для которых я хочу обеспечить работу единого входа через свое приложение. Целью развертывания моего приложения является iOS 11, что означает, что AppAuth внутренне использует SFAuthenticationSession, Я использую поток авторизации, что означает, что пользователю предоставляется веб-страница входа через SFAuthenticationSession, Когда пользователь заполняет и отправляет учетные данные SFAuthenticationSession завершение вызова с URL (если успешно), с которого авторизация code можно разобрать. С разрешения code POST-запрос токена через URLSession сделан независимо от SFAuthenticationSession и access_token получено

Весь поток успешен, включая поиск access_token, но когда я покидаю приложение и открываю веб-страницу профиля пользователя, предоставленную поставщиком услуг в Safari, пользователь не входит в систему. Я протестировал тот же поток с учетной записью Google ( https://accounts.google.com/), и SSO сработал хорошо, например, когда я открыл https://mail.google.com/ в Safari, я вошел в систему. Поэтому у меня есть подозрение, что мой поставщик услуг что-то делает не так. Возможно, они не предоставили мне правильные возможности? Но прежде чем связаться с ними, я хочу исключить любую мою ошибку. Теперь моя самая непосредственная мысль заключается в том, что файлы cookie, связанные с сеансом, не сохраняются в Safari. Из этого вытекает мой вопрос.

Мой вопрос. POST-запрос токена выполняется независимо от SFAuthenticationSession (другой пользовательский агент), так как любые куки, связанные с сеансом, сохраняются на устройстве (Safari), если не через SFAuthenticationSession? И есть ли способ отладки файлов cookie в коде?

2 ответа

Решение

Согласно стандарту OAuth 2.0 конечная точка токена не требует аутентификации владельца ресурса, в отличие от конечной точки авторизации, которая этого требует. (Сценарий или обратный канал, выполняющий обмен кодами авторизации, не обязательно имеет доступ к HTTP-cookie, установленным в пользовательском агенте, и по умолчанию браузеры не включают учетные данные в межсайтовые XHR. Когда используется токен обновления, владелец ресурса взаимодействие вообще не требуется.) Ваш URLSession не получает сессионный cookie от Safari или SFAuthenticationSession и не должен нуждаться в этом.

Что касается вашего мобильного Safari, документы для ASWebAuthenticationSession, SFAuthenticationSession преемник, государство:

Все файлы cookie, кроме файлов cookie сеанса, могут быть переданы в Safari.

Кажется, дело в SFAuthenticationSession также. Google должен использовать постоянные файлы cookie, и в результате с ними работает общий доступ к сеансам.

Кроме того, даже при наличии постоянных файлов cookie возникает некоторая несогласованность в синхронизации файлов cookie в среде iOS 11, например: http://www.openradar.me/radar?id=5036182937272320

Для отладки куки вы можете использовать этот код

импорт UIKit

импортировать WebKit

Класс ViewController: UIViewController, WKNavigationDelegate {

var webView: WKWebView?

override func viewDidLoad() {
    super.viewDidLoad()

    let configuration = WKWebViewConfiguration()
    webView = WKWebView(frame: .zero,configuration:configuration)
    self.view = webView
}

override func viewDidAppear(_ animated: Bool) {
    let url = URL(string: "YOUR URL")

    let request = URLRequest(url: url!)

    webView?.navigationDelegate = self
    webView?.addObserver(self, forKeyPath: "URL", options: [.new, .old], context: nil)

    self.webView?.load(request)
}

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {

    if let newValue = change?[.newKey] as? Int, let oldValue = change?[.oldKey] as? Int, newValue != oldValue {

        print("NEW",change?[.newKey])
    } else {
        print("OLD",change?[.oldKey])

    }

    webView?.configuration.websiteDataStore.httpCookieStore.getAllCookies { cookies in
        for cookie in cookies {
            print(cookie)
        }
    }
}

}

И проверьте, есть ли куки expiresDate имущество. Если нет, вы не сможете использовать SSO.

Если вы не хотите хранить файлы cookie в браузере, вы можете выполнить аутентификацию через частный сеанс просмотра с помощью ASWebAuthenticationSession с участием prefersEphemeralWebBrowserSession установлено значение true.

https://github.com/openid/AppAuth-iOS/issues/530

Другие вопросы по тегам