如何从iOS ADAL身份验证中注销?

7

我已经将ADAL库集成到我的iOS应用程序中,它正在正常工作。但现在我想从ADAL退出登录。我该如何注销?


你目前尝试了什么?请分享你所尝试的代码。 - Popeye
1
@Popeye,我已经尝试了这段代码[authContext.tokenCacheStore removeAllWithError:&error];,但是我在他们的文档中没有找到注销的代码。这是我遵循的链接https://github.com/AzureAD/azure-activedirectory-library-for-objc - Ganesh G
请在您的问题中更新您尝试过的代码。 - Popeye
这是ADALiOS 2.1版本的答案。http://stackoverflow.com/questions/36874719/how-can-i-logout-using-the-new-release-of-adalios-2-1 - jpanchal
4个回答

10
使用ADAL交互式流程时,有两个地方存储签入状态。一个是完全由应用程序控制的令牌缓存。调用[authContext.tokenCacheStore removeAllWithError:&error] 是清除所有缓存令牌并停止ADAL无需启动浏览器即可登录的好方法。
但是,服务器也会在浏览器cookie中跟踪签入状态。服务器将记住用户登录到服务器的状态,直到cookie超时或被删除。当ADAL检查缓存并未找到合适的令牌时,它会启动webView。服务器将找到cookie并静默地签入用户。浏览器cookie在ADAL中大部分是隐藏的。ADAL库可能提供一个注销函数来清除所有cookie,但如果应用程序因某种原因依赖于其他cookie,则会产生副作用。
有几种解决方法。如果您只想注销,而且不介意清除所有webView cookie,那么在清除缓存后,按照此处所述的方式清除所有浏览器cookie:How to delete all cookies of UIWebView? 这是一个核选项。另一个更微妙的选择是清除缓存,然后在调用带有ADPromptBehavior参数的aquireToken时使用AD_PROMPT_ALWAYS值。当你使用AD_PROMPT_ALWAYS时,会向AAD发送一个标志,导致它忽略cookies并向用户显示一个新的提示。这将使cookies保持不变,因此从技术上讲,用户实际上并没有注销。对于用户来说,他们似乎已经注销并且可以稍后再次登录。当他们再次登录时,如果愿意,他们可以选择其他用户。
这也是处理多个用户登录的方式。如果您已经有一个用户登录,但想添加另一个用户,请勿清除缓存,并在下一次调用acquireToken时传递AD_PROMPT_ALWAYS。服务器将显示一个新的登录提示并返回一个新的令牌。通过调用acquireToken并传递userId,您可以为特定用户获取令牌。

6
这段Swift 3代码对我有用(ADAL 2.5.1):
销毁密钥库:
guard let clientId = getAuthConfig().clientId else {
            // freak out
            print("Auth.logout: I freaked out getting the client ID ")
            return
        }
        ADKeychainTokenCache.defaultKeychain().removeAll(forClientId: clientId, error: nil)

并清除cookies:

let cookieJar = HTTPCookieStorage.shared
guard let cookies = cookieJar.cookies else { return }
let cookiesArr = Array(cookies)
for cookie: HTTPCookie in cookiesArr {
    print(cookie.name)
    if (cookie.name == "SignInStateCookie" || cookie.name == "ESTSAUTHPERSISTENT" || cookie.name == "ESTSAUTHLIGHT" || cookie.name == "ESTSAUTH" || cookie.name == "ESTSSC") {
        cookieJar.deleteCookie(cookie)
    }
}

4
更新Rich的优秀答案。首先,最新ADAL版本中接口已经改变,您需要以以下方式访问令牌缓存:
#import <ADAL/ADKeychainTokenCache.h>
[...]
[[ADKeychainTokenCache defaultKeychainCache] removeAllForClientId:ADFS_CLIENT_ID error:&error];

清除cookie时,我建议只删除相关的cookie而不是清除所有cookie:
NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for (NSHTTPCookie *cookie in [cookieJar cookies]) {
    if ([cookie.name isEqualToString:@"MSISAuth"] ||
        [cookie.name isEqualToString:@"MSISAuthenticated"] ||
        [cookie.name isEqualToString:@"MSISLoopDetectionCookie"]) {
        [cookieJar deleteCookie:cookie];
    }
}

我发现在旧版ADFS安装上,AD_PROMPT_ALWAYS无法使用,只能删除cookies。

0

根据最新版本进行更新:

没有共享的 cookie 可供我们控制并使我们能够删除它们所有:

let cookieJar = HTTPCookieStorage.shared
    if let cookies = cookieJar.cookies {
        let cookiesArray = Array(cookies)
        for cookie: HTTPCookie in cookiesArray {
            if (cookie.name == "SignInStateCookie" ||
                cookie.name == "ESTSAUTHPERSISTENT" ||
                cookie.name == "ESTSAUTHLIGHT" ||
                cookie.name == "ESTSAUTH" ||
                cookie.name == "ESTSSC" ||
                cookie.name == "MSISAuth" ||
                cookie.name == "MSISAuthenticated" ||
                cookie.name == "MSISLoopDetectionCookie" ) {
                cookieJar.deleteCookie(cookie)
            }
        }
    }

在这里输入图像描述 所以实际上这并不起作用。

我找到的解决方案是在MSALInteractiveTokenParameters配置中选择提示类型为login:

let webviewParameters = MSALWebviewParameters.init(authPresentationViewController: VC)
let parameters = MSALInteractiveTokenParameters(
    scopes: scopes,
    webviewParameters: webviewParameters
)
parameters.promptType = .login

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接