我正在尝试一个能够显示所有内容并为Outlook日历创建新事件的应用程序。我正在使用MSAL库获取身份验证代码。问题是,尽管当我触摸输入或取消按钮时出现登录屏幕,但我没有注意到任何反应。这是我的代码:
class OutlookManagerController: BaseViewController {
let oClientKey = "a07745a5-3b90-4385-a2b2-8223dbf68688"
let authScopes = ["openid+https://outlook.office.com/contacts.read+offline_access"]
func getAcessToken(){
if let application = try? MSALPublicClientApplication.init(clientId: oClientKey) {
application.acquireToken(forScopes: authScopes) { (result, error) in
if result != nil {
let userToken = result!.accessToken!
print(userToken)
} else {
print(error!.localizedDescription)
}
}
}
else {
print("Unable to create application.")
}
}
}
最佳答案
看来您没有在听SFSafariViewController
时从MSCC启动的AcquireToken()
返回认证码。 MSAL使用SFSafariViewController
进行登录,以提高安全性并在应用程序之间提供单点登录。您只需要设置一个重定向URI,即可调用您的应用程序并为您的租户使用正确的Issuer。
这就是您遇到的问题。登录成功,但是Azure找不到回到您应用程序的方式!
首先,一些基础。
系统网页视图
现在,大多数现代OAuth2库都使用System Webview来登录用户。System Webview是一个浏览器组件,应用程序可以启动该浏览器组件,该组件似乎是应用程序的一部分,但实际上是一个独立的进程,用于运行操作系统的Web浏览器。对于iOS,这是SFSafariViewController
,在Android上是Chrome Custom Tabs
。
System Webview用来吸引用户的好处很多,包括:
更好的安全性。应用程序是隔离的浏览器进程,因此无法访问在System Webview中键入的凭据。
如今,许多应用程序使用用户名和密码形式或嵌入式Web视图来获取凭据。这允许应用程序侦听并获取这些凭据。许多公司已经开始禁止具有这种登录功能的应用程序。系统Webviews确保您的应用程序没有此问题。
单一登录。用户使用System Webview登录后,将在浏览器中放置一个cookie,该帐户可用于任何应用程序,从而避免了用户分别登录每个应用程序的需要。
随着越来越多的消费者和企业将电话短信和其他因素作为附加步骤使用,必须重做此步骤以及使用密码对客户而言变得非常烦人。系统Webview消除了此问题。
更好的控制。用户可以选择提供应用程序的帐户,或者在系统Web视图中添加全新的帐户(如果支持)。
您已经看到Google和Microsoft使用我们最新的SDK过渡到System Webview并更新了我们的身份服务,这是为了向客户提供这些保护和功能。 OpenID项目中的App Auth也提供了这种支持,该项目具有Google和Microsoft工程师共同贡献的代码。
系统Webview需要返回到您的应用程序
阅读以上内容可能发生的事情之一是:
如果应用程序现在调用系统Webview进行登录,并且无法对其进行控制,如何从系统Webview中取回需要的令牌?
答案是,您必须利用每个操作系统必须回调应用程序的机制,然后使用OAuth2协议中的redirectURI
使用该机制将响应返回给该应用程序。几乎完全像它在网络浏览器中的工作方式。您从网站重定向到身份提供者进行登录,然后身份提供者使用redirectURI
将用户带回响应的令牌返回网站。
对于iOS,这是通过“自定义网址方案”完成的。 URL格式为CFBundleURLScheme:\\CFBundleURLSchemes
,定义为:
CFBundleURLName
包含URL方案抽象名称的字符串。为确保唯一性,建议您指定标识符的反向DNS样式,例如com.acme.myscheme。
您指定的字符串还用作应用程序的InfoPlist.strings文件中的键。密钥的值是人类可读的方案名称。
CFBundleURLSchemes
包含URL方案名称的字符串数组,例如,http,mailto,tel和sms。
要为您的应用注册网址类型,请在应用的CFBundleURLTypes
文件中包含Info.plist
键。 CFBundleURLTypes
键包含一个字典数组,每个字典都定义了应用程序支持的URL方案。
如何获取系统Webview返回到您的应用程序
因此,结合这两件事,您要做的事情就很简单了:
找出适用于您应用的URL方案(例如appauth://abc123
)。
告诉Azure AD您的新URL方案是什么,并将其添加为应用程序的另一个redirectURI
。
配置您的应用程序以侦听此URL方案并启动该应用程序
一旦此URL方案启动您的应用程序,就将应用程序本身配置为获取令牌(应用程序身份验证以及我们自己的MSAL库,为您执行此操作!)
1.确定您的应用程序的URL方案
您可以从Apple的App-App Communication文档中阅读如何制作URL方案,但是我们建议您使用appauth://<client id>
方案(例如appauth://ab032846-efee-481f-b6bc-493aae92c432
)
2.告诉Azure AD您的新URL方案是什么
您需要将此URL方案作为RedirectURI添加到您的应用程序。这很容易做到。只需访问https://apps.dev.microsoft.com/并选择您的应用程序。向下滚动到Native Applications
下的“自定义应用URI”,然后添加新的redirectURI!
3.配置您的应用程序以侦听此URL方案
按照Apple在应用程序间通信中的说明,将以下内容添加到您的info.plist
文件中。它看起来应该像这样,尽管不同的应用程序将注册不同的URL方案,以及其他URL方案:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>ab032846-efee-481f-b6bc-493aae92c432</string>
<key>CFBundleURLSchemes</key>
<array>
<string>app-auth</string>
</array>
</dict>
</array>
4.配置应用程序本身以获取令牌
尽管对于所有iOS应用程序而言,侦听从Web浏览器返回给应用程序的响应都是一种众所周知的模式,但实际实现因所使用的身份SDK而异。对于MSAL,在您的
AppDelegate.m
文件中输入以下代码:func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
print("Received callback!")
MSALPublicClientApplication.handleMSALResponse(url)
return true
}
一旦了解了以上背景,该代码就很容易理解。这一切都是通过获取返回的URL,然后将该URL中的所有内容提供回应用程序,从而从身份服务接收响应,以便它可以获取继续工作所需的令牌。
而已!
您的应用现在应该可以与Azure Active Directory一起使用。系统Web视图的这种模式在许多身份提供商(Microsoft,Google,Facebook)和移动平台中都是常见的。
这记录在我们的sample application here中。
关于ios - MSAL库登录无响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44374931/