自定义 iOS/macOS 的浏览器和 WebView

完成交互式身份验证需要使用 Web 浏览器。 在 iOS 和 macOS 10.15+ 上,Microsoft 身份验证库 (MSAL) 默认使用系统 Web 浏览器(可能显示在应用的顶部)执行交互式身份验证,以将用户登录。 使用系统浏览器的好处是可与其他应用程序和 Web 应用程序共享单一登录 (SSO) 状态。

可以通过将配置自定义为其他用于显示 Web 内容的选项来更改体验,例如:

仅对 iOS 而言:

对于 iOS 和 macOS:

MSAL for macOS 仅在较早的 OS 版本上支持 WKWebView。 仅在 macOS 10.15 及更高版本上支持 ASWebAuthenticationSession

系统浏览器

对于 iOS,ASWebAuthenticationSessionSFAuthenticationSessionSFSafariViewController 被视为系统浏览器。 对于 macOS,只有 ASWebAuthenticationSession 可用。 一般情况下,系统浏览器将与 Safari 浏览器应用程序共享 Cookie 和其他网站数据。

默认情况下,MSAL 会动态检测 iOS 版本,并选择适用于该版本的建议系统浏览器。 在 iOS 12+ 上,系统浏览器为 ASWebAuthenticationSession

iOS 的默认配置

版本 Web 浏览器
iOS 12+ ASWebAuthenticationSession
iOS 11 SFAuthenticationSession
iOS 10 SFSafariViewController

macOS 的默认配置

版本 Web 浏览器
macOS 10.15+ ASWebAuthenticationSession
其他版本 WKWebView

开发人员还可为 MSAL 应用选择不同的系统浏览器:

  • SFAuthenticationSessionASWebAuthenticationSession 在 iOS 11 中的版本。
  • SFSafariViewController 更通用,提供用于浏览 Web 的接口,并且还可用于登录。 在 iOS 9 和10中,Cookie 和其他网站数据将与 Safari 共享 -- 但 iOS 11 和更高版本中不提供这种共享。

应用中浏览器

WKWebView 是显示 Web 内容的应用中浏览器。 它不与其他 WKWebView 实例或 Safari 浏览器共享 Cookie 或网站数据。 WKWebView 是同时适用于 iOS 和 macOS 的跨平台浏览器。

所用浏览器共享 Cookie 的方式会影响 SSO 体验。 下表汇总了每个浏览器的 SSO 体验。

技术 浏览器类型 iOS 可用性 macOS 可用性 共享 Cookie 和其他数据 MSAL 可用性 SSO
ASWebAuthenticationSession 系统 iOS12 和更高版本 macOS 10.15 和更高版本 iOS 和 macOS 10.15+ 具有 Safari 实例
SFAuthenticationSession 系统 iOS11 和更高版本 空值 仅限 iOS 具有 Safari 实例
SFSafariViewController 系统 iOS11 和更高版本 空值 仅限 iOS 否**
SFSafariViewController 系统 iOS10 空值 仅限 iOS 具有 Safari 实例
WKWebView 应用中 iOS8 和更高版本 macOS 10.10 和更高版本 iOS 和 macOS 否**

** 要正常进行 SSO,需要在应用之间共享令牌。 这需要使用令牌缓存或中介应用程序,例如适用于 iOS 的 Microsoft Authenticator。

更改请求的默认浏览器

可以根据 UX 要求使用应用中浏览器或特定的系统浏览器,只需在 MSALWebviewParameters 中更改以下属性即可:

@property (nonatomic) MSALWebviewType webviewType;

按交互式请求进行更改

可以通过更改 MSALInteractiveTokenParameters.webviewParameters.webviewType 属性,然后将其传递给 acquireTokenWithParameters:completionBlock: API,将每个请求配置为替代默认浏览器。

此外,MSAL 还支持通过设置 MSALInteractiveTokenParameters.webviewParameters.customWebView 属性来传入自定义 WKWebView

例如:

Objective-C

UIViewController *myParentController = ...;
WKWebView *myCustomWebView = ...;
MSALWebviewParameters *webViewParameters = [[MSALWebviewParameters alloc] initWithAuthPresentationViewController:myParentController];
webViewParameters.webviewType = MSALWebviewTypeWKWebView;
webViewParameters.customWebview = myCustomWebView;
MSALInteractiveTokenParameters *interactiveParameters = [[MSALInteractiveTokenParameters alloc] initWithScopes:@[@"myscope"] webviewParameters:webViewParameters];

[app acquireTokenWithParameters:interactiveParameters completionBlock:completionBlock];

Swift

let myParentController: UIViewController = ...
let myCustomWebView: WKWebView = ...
let webViewParameters = MSALWebviewParameters(authPresentationViewController: myParentController)
webViewParameters.webviewType = MSALWebviewType.wkWebView
webViewParameters.customWebview = myCustomWebView
let interactiveParameters = MSALInteractiveTokenParameters(scopes: ["myscope"], webviewParameters: webViewParameters)

app.acquireToken(with: interactiveParameters, completionBlock: completionBlock)

如果使用自定义 webview,则会使用通知来指示显示的 Web 内容的状态,例如:

/*! Fired at the start of a resource load in the webview. The URL of the load, if available, will be in the @"url" key in the userInfo dictionary */
extern NSString *MSALWebAuthDidStartLoadNotification;

/*! Fired when a resource finishes loading in the webview. */
extern NSString *MSALWebAuthDidFinishLoadNotification;

/*! Fired when web authentication fails due to reasons originating from the network. Look at the @"error" key in the userInfo dictionary for more details.*/
extern NSString *MSALWebAuthDidFailNotification;

/*! Fired when authentication finishes */
extern NSString *MSALWebAuthDidCompleteNotification;

/*! Fired before ADAL invokes the broker app */
extern NSString *MSALWebAuthWillSwitchToBrokerApp;

选项

MSAL 支持的所有 Web 浏览器类型都在 MSALWebviewType 枚举中声明

typedef NS_ENUM(NSInteger, MSALWebviewType)
{
    /**
     For iOS 11 and up, uses AuthenticationSession (ASWebAuthenticationSession or SFAuthenticationSession).
     For older versions, with AuthenticationSession not being available, uses SafariViewController.
     For macOS 10.15 and above uses ASWebAuthenticationSession
     For older macOS versions uses WKWebView
     */
    MSALWebviewTypeDefault,

    /** Use ASWebAuthenticationSession where available.
     On older iOS versions uses SFAuthenticationSession
     Doesn't allow any other webview type, so if either of these are not present, fails the request*/
    MSALWebviewTypeAuthenticationSession,

#if TARGET_OS_IPHONE

    /** Use SFSafariViewController for all versions. */
    MSALWebviewTypeSafariViewController,

#endif
    /** Use WKWebView */
    MSALWebviewTypeWKWebView,
};

后续步骤

详细了解身份验证流和应用程序方案