首页 > 解决方案 > 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 有什么影响?

标签: iosazure-active-directory

解决方案


这是我用来从使用 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
}

推荐阅读