ios - iOS:退出后 ADAL 自动登录
问题描述
我在我的 iOS 应用程序中使用 ADAL v2.5.4 自动登录时遇到问题。
当用户想要登录 MSA 帐户时,我们使用所需的参数和 promptBehavior 调用 acquireTokenWithResource 作为 AD_PROMPT_AUTO。在应用程序的第一次运行中,向用户显示了登录流程按预期工作的 web 视图,因为用户已成功登录。
在我的应用程序中单击“退出”时,我将删除所有具有我的应用程序 ClientID 的令牌。在这一点上,我看到缓存中仍然存在一个带有 ClientID 'foci-1' 的令牌。此外,我正在清除我的应用程序的 cookie 存储,以便 webview 不会重用任何 cookie。
当用户希望再次登录时,就会出现问题。当再次触发相同的登录流程时,现在用户会自动登录。在日志中我看到'1 token found for query'。理想情况下,由于用户较早退出,应再次提示他们输入凭据。
处理这种情况的正确方法是什么?是否应该以不同的方式处理注销?在重新触发登录之前是否应该进行任何其他检查?在这种情况下 promptBehavior 有什么影响?
解决方案
这是我用来从使用 ADAL 的应用程序中执行“注销”的代码。
它调用注销端点以使服务器端的刷新令牌无效,并删除所有相关的 cookie 和钥匙串条目。
fileprivate var safariModal = false
fileprivate var safariHostVC: UIViewController?
public func logout(presentOn viewController: UIViewController?, modal: Bool) {
let client = "xyzzy" // Your app client id here
let redirect = "youruri://somepath/" // Your redirect URI here
ADKeychainTokenCache.defaultKeychain().removeAll(forClientId: clientid, error: nil)
if let url = URL(string:"https://login.microsoftonline.com/common/oauth2/logout?post_logout_redirect_uri=\(redirect)") {
let safari = SFSafariViewController(url: url)
safari.toolbarItems = nil
safari.delegate = self
if #available(iOS 11.0, *) {
safari.dismissButtonStyle = .close
}
guard let vc = viewController else {
return
}
self.safariHostVC = vc
self.safariModal = modal
safari.modalPresentationStyle = .overFullScreen
safari.modalTransitionStyle = .coverVertical
if modal {
vc.present(safari, animated: true, completion: nil)
} else {
vc.navigationController?.pushViewController(safari, animated: true)
}
let cookieJar = HTTPCookieStorage.shared
guard let cookies = cookieJar.cookies else { return }
let cookiesArr = Array(cookies)
for cookie: HTTPCookie in cookiesArr {
if (cookie.name == "SignInStateCookie" || cookie.name == "ESTSAUTHPERSISTENT" || cookie.name == "ESTSAUTHLIGHT" || cookie.name == "ESTSAUTH" || cookie.name == "ESTSSC") {
cookieJar.deleteCookie(cookie)
}
}
}
}
您还需要实现一个SFSafariViewControllerDelegate
功能
func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
guard let vc = self.safariHostVC else {
return
}
if self.safariModal {
vc.dismiss(animated: true, completion: nil)
} else {
vc.navigationController?.popViewController(animated: true)
}
self.safariHostVC = nil
}
推荐阅读
- python - 如何匹配绳索中的多个参数?
- wicket - 检票口 JQWicket - 检票口
- php - 无法从 ASP Msxml2.ServerXMLHTTP.6.0 对象调用的 PHP 设置 cookie
- reactjs - 如何在减速器中调用动作?
- angular - ionic v4 导航错误
- c# - WPF - 害羞的标题
- javascript - 如何解决错误:“对预检请求的响应未通过访问控制检查”
- html - 如何将普通的 flexbox nav 变成响应式汉堡移动菜单?
- angularjs - iframe 在 IE 和 firefox 中无法使用 angularjs 路由
- openlayers - EventListener mouseup 或 mousedown 自 5.2.0 起不起作用