OktaWebAuthenticationUI 1.8.2

OktaWebAuthenticationUI 1.8.2

Mike Nachbaur维护。



 
依赖项
OktaAuthFoundation= 1.8.2
OktaOAuth2= 1.8.2
 

  • Okta开发者

License Support API Reference

Okta Mobile SDK for Swift

Okta Mobile SDK取代了我们的传统移动SDK(如okta-oidc-ios),并能够

  • 简化开发
  • 提高您代码中Okta部分的维护性
  • 更容易扩展新功能
  • 支持之前难以或无法实施的使用案例。

这个新的SDK作为一个平台来构建,允许您选择您的应用程序所需的功能组件。

目录

发布状态

此库使用语义版本控制,并遵循Okta的库版本策略

版本 状态
1.4.2 ✔️稳定

最新发布版本始终可在发布页面找到。

需要帮助?

如果您在使用SDK时遇到问题,您可以

SDK 架构

此SDK包含几个不同的库,每个库都有详细的文档。

  graph TD;
    AuthFoundation-->OktaOAuth2;
    OktaOAuth2-->WebAuthenticationUI;
  • AuthFoundation -- 用于管理凭证的公共类,也是其他库的基础。
  • OktaDirectAuth -- 用于高级无浏览器认证(EA)的直接认证功能。
  • OktaOAuth2 -- 用于高级用例的OAuth2认证功能。
  • WebAuthenticationUI -- 使用基于Web的OIDC流程进行用户认证。

此SDK使您能够构建或支持各种各样的认证流程和方案。

开发路线图

此SDK正在积极开发中,计划进行未来扩展。目前,我们正在积极征求开发者社区的反馈,以评估以下内容:

  • 整体SDK及其组件
  • API和整体开发者体验
  • 可能遗漏或与您的应用程序需求不一致的使用案例或功能
  • 对未来开发的建议
  • 对这一新方向的任何其他评论或反馈。

关键特性

此库引入了几个关键特性和功能,以下列举了其中一些显著的改进。

功能
简单基于OIDC的Web登录
凭证管理(安全存储、检索等)
多令牌处理(为多个用户、作用域等存储和使用令牌)
授权码流
原生SSO/令牌交换流
设备授权授予流
资源所有者流
简化JWT解析和处理
使用凭证令牌简化URLSession请求的授权
许多扩展点,适用于定制、监控和跟踪

开始使用

要开始使用,您需要以下内容

  • 一个 Okta 账户,称为 组织(如果您需要,请免费注册一个开发者组织)。
  • 一个配置为 "原生应用" 的 Okta 应用程序。使用 Okta 管理员控制台,通过向导器并使用默认属性创建应用程序。
  • Xcode 13.x,针对以下支持的平台和目标版本(请参阅下方的支持策略)。

有关如何使用此 SDK 的示例,请参阅本存储库中包含的 示例应用程序

安装

Swift 包管理器

将以下内容添加到您的 Package.swift 文件中定义的 dependencies 属性。您可以使用 majorVersionminor 参数选择版本。例如

dependencies: [
    .Package(url: "https://github.com/okta/okta-mobile-swift.git", majorVersion: <majorVersion>, minor: <minor>)
]

CocoaPods

只需在您的 Podfile 中添加以下行

pod 'OktaWebAuthenticationUI'

然后将其安装到您的项目中

pod install --repo-update

如果您只想使用 OktaOAuth2 库,请使用以下命令

pod 'OktaOAuth2'

如果您正在参与 Okta Direct Authentication API 的早期访问预览,请使用以下命令

pod 'OktaDirectAuth'

使用说明

使用OIDC进行网络身份验证

在您的应用中集成身份验证最简单的方式是通过网络浏览器,利用授权代码流许可进行OIDC。

配置您的OIDC设置

在您对用户进行身份验证之前,您需要使用在Okta开发者控制台中定义的设置创建您的客户端配置。最简单的方法是使用一个Okta.plist配置文件来指定这些设置。确保创建了以下字段:

<?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>issuer</key>
    <string>https://{yourOktaDomain}.com</string>
    <key>clientId</key>
    <string>{clientId}</string>
    <key>redirectUri</key>
    <string>{redirectUri}</string>
    <key>logoutRedirectUri</key>
    <string>{logoutRedirectUri}</string>
    <key>scopes</key>
    <string>openid profile offline_access</string>
  </dict>
</plist>

或者,您也可以在下一节中将要讨论的WebAuthentication构造函数中提供这些值。

创建一个网络身份验证会话

一旦您在Okta.plist文件中配置完应用程序设置,共享配置将通过WebAuthentication.shared单例属性自动可用。配置完成后,您可以使用便捷的WebAuthentication.signIn(from:)方法提示用户登录。

import WebAuthenticationUI

func signIn() async {
    let token = try await WebAuthentication.signIn(from: view.window)
    let credential = try Credential.store(token)
}

signIn(from:)函数返回一个令牌,通过使用Credential类,您可以在您的应用程序中保存此令牌并使用它。

使用设备代码流授权进行身份验证

对于无头设备或难以使用键盘的设备(例如AppleTV),您的应用程序可以使用OktaOAuth2直接与DeviceAuthorizationFlow类配合使用。这将使您能够向用户提供一个易于记忆的代码,他们可以在另一台设备上使用该代码来授权您的应用程序。

使用方法很简单

  1. 创建一个DeviceAuthorizationFlow的实例
let flow = DeviceAuthorizationFlow(
    issuer: URL(string: "https://example.okta.com")!,
    clientId: "abc123client",
    scopes: "openid offline_access email profile")
  1. 启动一个身份验证会话以接收代码和授权URL,然后向用户展示。
let context = try await flow.start()
let code = context.userCode
let uri = context.verificationUri
  1. 等待用户从另一台设备授权应用程序。
let token = try await flow.resume(with: context)

使用原生SSO流程进行身份验证

当使用device_sso作用域时,您的应用程序可以接收一个“设备密钥”,这可以与您的用户ID令牌结合使用来交换新的凭据。要在应用程序中使用此功能,您将使用TokenExchangeFlow来交换这些令牌集。

let flow = TokenExchangeFlow(
    issuer: URL(string: "https://example.okta.com")!,
    clientId: "abc123client",
    scopes: "openid offline_access email profile",
    audience: .default)

let token = try await flow.start(with: [
    .actor(type: .deviceSecret, value: "DeviceToken"),
    .subject(type: .idToken, value: "IDToken")
])

使用用户名和密码进行身份验证

对于简单的身份验证用例,您可以使用ResourceOwnerFlow类使用纯文本用户名和密码进行身份验证。

注意:ResourceOwnerFlow类已被标记为已弃用,因为其功能正被更全面的OktaDirectAuth库取代。

let flow = ResourceOwnerFlow(issuer: URL(string: "https://example.okta.com")!,
                             clientId: "abc123client",
                             scopes: "openid offline_access email profile")
let token = try await flow.start(username: "jane.doe", password: "secretPassword")

使用直接认证进行身份验证

对于简单的身份验证用例,您可以使用ResourceOwnerFlow类使用纯文本用户名和密码进行身份验证。

注意: Okta Direct Authentication API 目前已标记为早期访问(EA),目前尚未普遍可用。

let flow = DirectAuthenticationFlow(issuer: URL(string: "https://example.okta.com")!,
                                    clientId: "abc123client",
                                    scopes: "openid offline_access email profile")
switch try await flow.start("[email protected]", with: .password("secretPassword")) {
    case .success(let token):
        // Store the token
    case .mfaRequired(_):
        // Continue authentication
}

有关更多信息,请参阅OktaDirectAuth API 文档

存储和使用令牌

一旦用户完成身份验证并创建了Token对象,应用程序可以存储和使用这些凭证。最直接的方法是使用Credential.store(_:tags:security:)函数。

let credential = try Credential.store(token)

为了方便起见,SDK在Credential类上提供了一个default静态属性。这提供了一种简单的方式来识别用户是否已进行身份验证,并快速访问用户的凭证。存储新凭证时,如果没有已经存储的凭证,它会自动作为默认凭证分配。

if let credential = Credential.default {
    // The user is signed in. Start by refreshing it.
    try await credential.refreshIfNeeded()
}

通过唯一标识符查找凭证

当存储令牌时,它会被分配一个唯一的ID,这可以用来区分不同的令牌,并在之后检索令牌。

let tokenId = token.id

// Later, retrieve the token
if let credential = try Credential.with(id: tokenId) {
    // Use the credential
}

使用自定义标签分配和查找证书

对于更复杂的应用,您可能需要管理多个证书(例如多用户登录、不同应用程序扩展的不同令牌、应用程序不同部分的细粒度作用域等)。为了更容易区分证书,您可以给它们分配标签,这些标签以后可以用来识别它们。

try Credential.store(token, tags: ["customTag": "someValue"])

可以通过这些标签检索证书。

if let credential = try Credential.find(where: { $0.tags["customTag"] == "someValue" }).first {
    // Use the credential
}

证书的标签可通过其 tags 属性访问,并且可以在事后修改。

if !credential.tags.contains("someCustomTag") {
    credential.tags["someCustomTag"] = "someValue"
}

// Or use the following method to intercept exceptions
try credential.setTags(["customTag": "someValue"])

使用ID令牌声明查找证书

此SDK简化了访问JWT令牌及其声明的操作。实际上,令牌的 idToken 属性自动作为 JWT 实例公开。使用它,您可以枚举并根据其令牌关联的声明检索证书。

if let credential = try Credential.find(where: { $0.email == "[email protected]" }).first {
    // Use the credential
}

速率限制处理

如果在一定时间内进行了太多请求,Okta API将返回429响应。请参阅Okta的速率限制以获取完全列出哪些端点是受速率限制的完整列表。此SDK在429错误上自动重试请求。默认配置如下

配置选项 描述
maximumCount 重试次数。默认值是 3

自定义速率限制

要自定义速率限制的处理方式,请遵守 APIClientDelegate 协议,实现 shouldRetry(request:rateLimit:) 方法,并将您的类作为适当的客户端的代理。当通过该客户端发送的任何请求收到 HTTP 429 错误响应时,它将允许您自定义速率限制行为。

import AuthFoundation

func login() {
    // Configure your authentication flow, before running the following command
    flow.client.add(delegate: self)
}

extension OAuth2Client {
    public func api(client: APIClient, shouldRetry request: URLRequest) -> APIRetry {
        return .doNotRetry
    }
}

有关更多信息,请参阅 APIRetry 枚举的 API 文档。

从遗留 SDK 迁移

此 SDK 集合旨在替代以下 SDK

如果您的应用程序当前使用 OktaOidc,已设置迁移现有用户到新 SDK 的可迁移性方案。有关更多信息,请参阅 SDKVersion.Migration 类的详细信息。

运行示例

有几个可用应用程序来演示此 SDK 的不同工作流。有关更多信息,请参阅示例应用程序

支持策略

本政策定义了对Xcode、Swift和平台(iOS、macOS、tvOS和watchOS)版本的支持范围。

Xcode

仅支持当前可用来提交应用程序到App Store的Xcode版本。一旦Xcode版本不再受支持,停止对它的支持将不会被视为破坏性变更,并将在次要版本中完成。

Swift

最低支持的Swift 5次要版本是与最老旧支持的Xcode版本一起发布的版本。一旦Swift 5次要版本不再受支持,停止对它的支持将不会被视为破坏性变更,并将在次要版本中完成。

平台

除非有平台限制限制了我们对旧版本的兼容性,否则仅支持最新的4个大版本平台。

平台 受支持 尽力
iOS 12.0 9.0
tvOS 12.0 10.0
watchOS 8.0 7.0
macCatalyst 13.0 13.0
macOS 12.0 10.11

一旦平台版本不再受支持,停止对它的支持将不会被视为破坏性变更,并将在次要版本中完成。例如,随着iOS 16的发布,iOS 12将不再受支持,可能在未来某个次要版本中停止支持。

对于macOS,每年的命名版本被视为此政策的大版本平台版本,无论实际版本号如何。

注意:旧操作系统版本采取尽力支持的策略。除非API限制阻碍SDK在旧操作系统版本上有效工作,否则最低要求将不会更改。

此外,Linux的兼容性被视为尽力支持,并非官方支持。

旧版 SDK 支持

在 okta-mobile-swift SDK 成为一般可用版本后,我们打算在此新库中继续所有新功能开发。我们计划在未来一段可预见的时间内,为 okta-oidc-ios(以及 okta-mobile-swift 取代的我们其他旧版 SDK)提供关键错误和安全修复。

开发

保护测试配置

此存储库在 Samples/Shared 中包含两个文件,用于向自动化测试以及示例应用程序公开测试凭据。

为了避免意外更改这些文件,建议在克隆此存储库后使用以下命令:

git config core.hooksPath ./.githooks

这将在提交更改之前运行检查,以确保这些文件未被更改。

运行测试

可以在 macOS 上使用以下命令从命令行运行测试:

swift test

或者,如果您想在 Linux 中运行测试,您可以使用 macOS 环境中的 Docker 来运行 Linux 测试。

docker run --rm --privileged --interactive --tty \
    --volume "$(pwd):/src" --workdir "/src" swift:5.6.1 \
    swift test

已知问题

贡献

我们很高兴接受贡献和PR。请参阅贡献指南了解如何构建贡献。