0

我正在尝试一个能够显示所有并为 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.")
        }
    }
}
4

2 回答 2

4

看起来您没有SFSafariViewController在调用AcquireToken(). MSAL 使用SFSafariViewController登录以实现更好的安全性并提供跨应用程序的单点登录。您只需要设置一个重定向 URI,它能够回调您的应用程序并为您的租户使用正确的颁发者。

这就是您遇到的问题。登录成功,但 Azure 找不到返回您的应用程序的方法!

首先,一些基础。

系统网页浏览

大多数现代 OAuth2 库现在使用 System Webview 来让用户登录。System Webview 是一个浏览器组件,应用程序可以启动它,它看起来是应用程序的一部分,但实际上是一个运行操作系统的 Web 浏览器的独立进程。对于 iOS,这是SFSafariViewController,在 Android 上是Chrome Custom Tabs

System Webview 对用户唱歌的好处很多,包括:

  • 更好的安全性。应用程序无法访问输入到系统 Web 视图的凭据,因为它是一个独立的浏览器进程。

    今天,许多应用程序使用用户名和密码表单或嵌入式 web 视图来获取凭据。这允许应用程序监听并获取这些凭据。许多公司已经开始禁止具有这种登录方式的应用程序。系统 Webviews 可确保您的应用程序没有此问题。

  • 单点登录。一旦用户使用 System Webview 登录,就会在浏览器中放置一个 cookie,并且该帐户可用于任何应用程序,从而无需用户单独登录每个应用程序。

    随着越来越多的消费者和企业利用电话短信和其他因素作为附加步骤,必须重做此步骤以及使用您的密码对客户来说变得非常烦人。系统 Webviews 消除了这个问题。

  • 更好的控制。用户可以选择提供应用程序的帐户,或者在系统 Web 视图中添加一个全新的帐户(如果支持)。

您已经看到 Google 和 Microsoft 使用我们最新的 SDK 过渡到此 System Webview 并更新了我们的身份服务,它为客户提供了这些保护和功能。来自 OpenID 项目的 App Auth(其代码由 Google 和 Microsoft 工程师等贡献)也提供此支持。

系统 Webview 需要返回到您的应用程序

阅读以上内容,您可能会想到的其中一件事是:

如果应用程序现在调用 System Webview 进行登录,并且无法控制它,我如何从 System Webview 获取我需要的令牌?

答案是您必须利用每个操作系统必须回调应用程序的机制,然后使用redirectURI来自 OAuth2 协议的机制使用该机制将响应返回给该应用程序。这几乎与在 Web 浏览器中的工作方式完全相同。您会从网站重定向到身份提供者进行登录,然后身份提供者使用 将redirectURI用户返回到网站,并在某处的响应中使用令牌。

对于 iOS,这是通过自定义 URL 方案完成的。URL 方案的格式为CFBundleURLScheme:\\CFBundleURLSchemes并定义为:

  • CFBundleURLName 一个字符串,包含 URL 方案的抽象名称。为确保唯一性,建议您指定反向 DNS 样式的标识符,例如 com.acme.myscheme。您指定的字符串也用作应用程序的 InfoPlist.strings 文件中的键。键的值是人类可读的方案名称。
  • CFBundleURLSchemes 包含 URL 方案名称的字符串数组,例如 http、mailto、tel 和 sms。

要为您的应用注册 URL 类型,请将CFBundleURLTypes密钥包含在您的应用Info.plist文件中。该CFBundleURLTypes键包含一个字典数组,每个字典都定义了应用程序支持的 URL 方案。

如何让系统 Web 视图返回到您的应用程序

因此,结合这两件事,您需要做的事情相当简单:

  1. 找出您的应用程序的 URL 方案(例如appauth://abc123.
  2. 告诉 Azure AD 你的新 URL 方案是什么,将它添加 redirectURI为你的应用程序的另一个方案。
  3. 配置您的应用程序以侦听此 URL 方案并启动应用程序
  4. 配置应用程序本身以在此 URL 方案启动您的应用程序后获取令牌(App Auth 以及我们自己的 MSAL 库,为您执行此操作!)

1. 弄清楚你的应用程序的 URL 方案是什么

您可以从 Apple 的 Inter-App Communication 文档中了解如何制作 URL 方案,但我们建议您使用appauth://<client id>(例如appauth://ab032846-efee-481f-b6bc-493aae92c432)的方案

2. 告诉 Azure AD 你的新 URL 方案是什么

您需要将此 URL 方案作为 RedirectURI 添加到您的应用程序。这很容易做到。只需访问https://apps.dev.microsoft.com/并选择您的应用程序。向下滚动到 Custom App URIs 下Native Applications并添加新的 redirectURI!

开发者门户中您需要输入此信息的位置的快照

3. 配置您的应用程序以侦听此 URL 方案

info.plist根据 Apple 在应用程序间通信中的说明将以下内容添加到您的文件中。它应该看起来像这样,尽管不同的应用程序会注册不同的附加 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.配置应用自己抓取token

尽管侦听从 Web 浏览器返回到应用程序的响应是所有 iOS 应用程序的众所周知的模式,但实际实现因您使用的身份 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)和移动平台中都很常见。

这记录在我们的示例应用程序中。

于 2017-06-06T00:31:46.000 回答
-1
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
    MSALPublicClientApplication.handleMSALResponse(url)
    return true
}
于 2017-06-05T18:22:59.563 回答