如何:在 macOS 和 iOS 上配置 SSOHow to: Configure SSO on macOS and iOS

适用于 macOS 和 iOS 的 Microsoft 身份验证库 (MSAL) 支持 macOS/iOS 应用与浏览器之间的单一登录 (SSO)。The Microsoft Authentication Library (MSAL) for macOS and iOS supports Single Sign-on (SSO) between macOS/iOS apps and browsers. 本文介绍以下 SSO 方案:This article covers the following SSO scenarios:

此类 SSO 在同一 Apple 开发商分发的多个应用之间进行。This type of SSO works between multiple apps distributed by the same Apple Developer. 它提供静默 SSO(即,不提示用户输入凭据):从密钥链读取其他应用写入的刷新令牌,并以静默方式使用这些刷新令牌交换访问令牌。It provides silent SSO (that is, the user isn't prompted for credentials) by reading refresh tokens written by other apps from the keychain, and exchanging them for access tokens silently.

重要

此流在 macOS 上不可用。This flow is not available on macOS.

Microsoft 提供称作“中介”的应用,只要移动设备已注册到 Azure Active Directory (AAD),这些应用就能在不同供应商提供的应用程序之间实现 SSO。Microsoft provides apps, called brokers, that enable SSO between applications from different vendors as long as the mobile device is registered with Azure Active Directory (AAD). 此类 SSO 要求在用户设备上安装一个中介应用程序。This type of SSO requires a broker application be installed on the user's device.

  • MSAL 与 Safari 之间的 SSOSSO between MSAL and Safari

SSO 是通过 ASWebAuthenticationSession 类实现的。SSO is achieved through the ASWebAuthenticationSession class. 它使用其他应用程序和 Safari 浏览器中的现有登录状态。It uses existing sign-in state from other apps and the Safari browser. 它并不局限于同一个 Apple 开发商分发的应用,但需要用户进行一些交互。It's not limited to apps distributed by the same Apple Developer, but it requires some user interaction.

如果在应用中使用默认 Web 视图将用户登录,基于 MSAL 的应用程序与 Safari 之间会自动实现 SSO。If you use the default web view in your app to sign in users, you'll get automatic SSO between MSAL-based applications and Safari. 若要详细了解 MSAL 支持的 Web 视图,请访问自定义浏览器和 WebViewTo learn more about the web views that MSAL supports, visit Customize browsers and WebViews.

重要

此类 SSO 目前在 macOS 上不可用。This type of SSO is currently not available on macOS. macOS 上的 MSAL 仅支持 WKWebView,但 Safari 并不提供 WKWebView 的 SSO 支持。MSAL on macOS only supports WKWebView which doesn't have SSO support with Safari.

  • ADAL 与 MSAL macOS/iOS 应用之间的静默 SSOSilent SSO between ADAL and MSAL macOS/iOS apps

MSAL Objective-C 支持基于 ADAL Objective-C 的应用的迁移和 SSO。MSAL Objective-C supports migration and SSO with ADAL Objective-C-based apps. 这些应用必须由同一家 Apple 开发商分发。The apps must be distributed by the same Apple Developer.

有关基于 ADAL 与基于 MSAL 的应用之间的跨应用 SSO 说明,请参阅 macOS 和 iOS 上 ADAL 与 MSAL 应用之间的 SSOSee SSO between ADAL and MSAL apps on macOS and iOS for instructions for cross-app SSO between ADAL and MSAL-based apps.

应用之间的静默 SSOSilent SSO between apps

MSAL 支持通过 iOS 密钥链访问组进行 SSO 共享。MSAL supports SSO sharing through iOS keychain access groups.

若要跨应用程序启用 SSO,需要执行以下步骤,后文对此做了详细说明:To enable SSO across your applications, you'll need to do the following steps, which are explained in more detail below:

  1. 确保所有应用程序使用相同的客户端 ID 或应用程序 ID。Ensure that all your applications use the same Client ID or Application ID.
  2. 确保所有应用程序共享来自 Apple 的相同签名证书,以便可以共享密钥链。Ensure that all of your applications share the same signing certificate from Apple so that you can share keychains.
  3. 请求每个应用程序的相同密钥链授权。Request the same keychain entitlement for each of your applications.
  4. 如果你要使用的共享密钥链不同于默认设置,请告知 MSAL SDK。Tell the MSAL SDKs about the shared keychain you want us to use if it's different from the default one.

使用相同的客户端 ID 和应用程序 IDUse the same Client ID and Application ID

为使 Microsoft 标识平台知道哪些应用程序可以共享令牌,这些应用程序需要共享相同的客户端 ID 或应用程序 ID。For the Microsoft identity platform to know which applications can share tokens, those applications need to share the same Client ID or Application ID. 这是在门户中注册第一个应用程序时提供的唯一标识符。This is the unique identifier that was provided to you when you registered your first application in the portal.

Microsoft 标识平台根据应用的重定向 URI 来辨别使用相同应用程序 ID 的应用。The way the Microsoft identity platform tells apps that use the same Application ID apart is by their Redirect URIs. 每个应用程序可以在登记门户中注册多个重定向 URI。Each application can have multiple Redirect URIs registered in the onboarding portal. 套件中的每个应用都具有不同的重定向 URI。Each app in your suite will have a different redirect URI. 例如:For example:

App1 重定向 URI: msauth.com.contoso.mytestapp1://authApp1 Redirect URI: msauth.com.contoso.mytestapp1://auth
App2 重定向 URI: msauth.com.contoso.mytestapp2://authApp2 Redirect URI: msauth.com.contoso.mytestapp2://auth
App3 重定向 URI: msauth.com.contoso.mytestapp3://authApp3 Redirect URI: msauth.com.contoso.mytestapp3://auth

重要

重定向 URI 的格式必须与 MSAL 支持的格式兼容,MSAL 重定向 URI 格式要求中阐述了此格式。The format of redirect uris must be compatible with the format MSAL supports, which is documented in MSAL Redirect URI format requirements.

设置在应用程序之间共享的密钥链Setup keychain sharing between applications

请参阅 Apple 的 Adding Capabilities(添加功能)一文来启用密钥链共享。Refer to Apple's Adding Capabilities article to enable keychain sharing. 重要的是,需要决定密钥链的调用方式,并将该功能添加到 SSO 涉及的所有应用程序。What is important is that you decide what you want your keychain to be called and add that capability to all of your applications that will be involved in SSO.

正确设置权利后,项目目录中会出现一个 entitlements.plist 文件,其中包含类似于以下示例的内容:When you have the entitlements set up correctly, you'll see a entitlements.plist file in your project directory that contains something like this example:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>keychain-access-groups</key>
    <array>
        <string>$(AppIdentifierPrefix)com.myapp.mytestapp</string>
        <string>$(AppIdentifierPrefix)com.myapp.mycache</string>
    </array>
</dict>
</plist>

添加新密钥链组Add a new keychain group

向项目功能添加新密钥链组。Add a new keychain group to your project Capabilities. 密钥链组应为:The keychain group should be:

  • iOS 上的 com.microsoft.adalcachecom.microsoft.adalcache on iOS
  • macOS 上的 com.microsoft.identity.universalstoragecom.microsoft.identity.universalstorage on macOS.

密钥链示例

有关详细信息,请参阅密钥链组For more information, see keychain groups.

配置应用程序对象Configure the application object

在每个应用程序中启用密钥链权利并准备好使用 SSO 后,请按以下示例所示在 MSALPublicClientApplication 中配置密钥链访问组:Once you have the keychain entitlement enabled in each of your applications, and you're ready to use SSO, configure MSALPublicClientApplication with your keychain access group as in the following example:

Objective-C:Objective-C:

NSError *error = nil;
MSALPublicClientApplicationConfig *configuration = [[MSALPublicClientApplicationConfig alloc] initWithClientId:@"<my-client-id>"];
configuration.cacheConfig.keychainSharingGroup = @"my.keychain.group";
    
MSALPublicClientApplication *application = [[MSALPublicClientApplication alloc] initWithConfiguration:configuration error:&error];

Swift:Swift:

let config = MSALPublicClientApplicationConfig(clientId: "<my-client-id>")
config.cacheConfig.keychainSharingGroup = "my.keychain.group"

do {
   let application = try MSALPublicClientApplication(configuration: config)
  // continue on with application
} catch let error as NSError {
  // handle error here
}

警告

在应用程序之间共享密钥链之后,任何应用程序都可以删除用户,甚至可以删除整个应用程序的所有令牌。When you share a keychain across your applications, any application can delete users or even all of the tokens across your application. 如果应用程序依赖于这些令牌来执行后台工作,后果特别严重。This is particularly impactful if you have applications that rely on tokens to do background work. 要共享密钥链,就必须十分警惕应用使用 Microsoft 标识 SDK 删除操作的情况。Sharing a keychain means that you must be very careful when your app uses Microsoft identity SDK remove operations.

就这么简单!That's it! Microsoft 标识 SDK 现在会在所有应用程序之间共享凭据。The Microsoft identity SDK will now share credentials across all your applications. 此外还会在应用程序实例之间共享帐户列表。The account list will also be shared across application instances.

在 iOS 上通过身份验证中介实现 SSOSSO through Authentication broker on iOS

MSAL 通过 Microsoft Authenticator 提供中介身份验证支持。MSAL provides support for brokered authentication with Microsoft Authenticator. Microsoft Authenticator 为已注册到 AAD 的设备提供 SSO。Microsoft Authenticator provides SSO for AAD registered device.

以下步骤说明如何使用身份验证中介为应用启用 SSO:The following steps are how you enable SSO using an authentication broker for your app:

  1. 为应用 Info.plist 中的应用程序注册中介兼容的重定向 URI 格式。Register a broker compatible Redirect URI format for the application in your app's Info.plist. 中介兼容的重定向 URI 格式为 msauth.<app.bundle.id>://authThe broker compatible Redirect URI format is msauth.<app.bundle.id>://auth. 请将 `<app.bundle.id>`` 替换为应用程序的捆绑 ID。Replace `<app.bundle.id>`` with your application's bundle ID. 例如:For example:

    <key>CFBundleURLSchemes</key>
    <array>
        <string>msauth.<app.bundle.id></string>
    </array>
    
  2. 将以下方案添加到应用的 Info.plist 中的 LSApplicationQueriesSchemes 下:Add following schemes to your app's Info.plist under LSApplicationQueriesSchemes:

    <key>LSApplicationQueriesSchemes</key>
    <array>
         <string>msauthv2</string>
         <string>msauthv3</string>
    </array>
    
  3. 将以下内容添加到 AppDelegate.m 文件以处理回调:Add the following to your AppDelegate.m file to handle callbacks:

    Objective-C:Objective-C:

    - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options
    {
        return [MSALPublicClientApplication handleMSALResponse:url sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]];
    }
    

    Swift:Swift:

    func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
        return MSALPublicClientApplication.handleMSALResponse(url, sourceApplication: options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String)
    }
    

如果使用的是 Xcode 11,应改为将 MSAL 回调放入 SceneDelegate 文件。If you are using Xcode 11, you should place MSAL callback into the SceneDelegate file instead. 如果支持兼容旧版 iOS 的 UISceneDelegate 和 UIApplicationDelegate,则需将 MSAL 回叫置于这两个文件中。If you support both UISceneDelegate and UIApplicationDelegate for compatibility with older iOS, MSAL callback would need to be placed into both files.

Objective-C:Objective-C:

 - (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts
 {
     UIOpenURLContext *context = URLContexts.anyObject;
     NSURL *url = context.URL;
     NSString *sourceApplication = context.options.sourceApplication;
     
     [MSALPublicClientApplication handleMSALResponse:url sourceApplication:sourceApplication];
 }

Swift:Swift:

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
        
        guard let urlContext = URLContexts.first else {
            return
        }
        
        let url = urlContext.url
        let sourceApp = urlContext.options.sourceApplication
        
        MSALPublicClientApplication.handleMSALResponse(url, sourceApplication: sourceApp)
    }

后续步骤Next steps

详细了解身份验证流和应用程序方案Learn more about Authentication flows and application scenarios