为您的用户提供 Apple 通行密钥 (Passkey) 解决方案。
IBM Security Verify WebAuthn Relying Party Kit for iOS 是客户端组件,与 IBM Security Verify WebAuthn Relying Party Server for Swift 配合使用,后者公开了托管在 Docker 镜像中的 REST API。
RelyingPartyKit 是一个轻量级框架,它使现有用户能够使用 Apple 通行密钥注册他们的设备,随后无需密码即可登录;新用户可以注册并验证他们的帐户。
如果您想了解更多关于开发启用通行密钥的应用程序的信息,请访问 Apple 开发者网站。
RelyingPartyKit 可作为 Swift Package Manager 包提供。要使用它,请在您的 Xcode 项目或 Package.swift
文件中将该包指定为依赖项。
.package(url: "https://github.com/ibm-security-verify/webauthn-relying-party-kit-ios.git")
此场景适用于您的身份系统中不存在用户,并且需要验证电子邮件地址所有权的情况。
import RelyingPartyKit
// The baseURL is the host of the relying party server.
let client = RelyingPartyClient(baseURL: URL(string: "https://example.com")!)
// The result is an OTPChallenge to correlate the email sent to the email address.
let result = try await client.signup(name: "Anne Johnson", email: "anne_johnson@icloud.com")
// Use the result.transactionId and the OTP value generated in the email to validate. If successful, the returned Token can be used to register for Passkey.
let token = try await client.validate(transactionId: result.transactionId, otp: "123456")
此场景验证具有用户名和密码的现有用户。
import RelyingPartyKit
// The baseURL is the host of the relying party server.
let client = RelyingPartyClient(baseURL: URL(string: "https://example.com")!)
// The result is a Token which can be used to register for Passkey.
let token = try await client.authenticate(username: "anne_johnson@icloud.com", password: "a1b2c3d4")
此场景要求用户使用有效的 Token
进行身份验证。基于 Cookie 的已验证用户可以使用 headers
参数,如果 Relying Party 服务器支持该参数。注册通行密钥使用 ASAuthorizationControllerDelegate 来处理平台密钥注册请求的结果。
import RelyingPartyKit
// The baseURL is the host of the relying party server.
let client = RelyingPartyClient(baseURL: URL(string: "https://example.com")!)
let token = try await client.authenticate(username: "account@example.com", password: "a1b2c3d4")
let nickname = "Anne's iPhone"
// First generate a challenge from the relying party server.
let result: CredentialRegistrationOptions = try await client.challenge(displayName: nickname, token: token)
// Construct a request to the platform provider with the challenge. The challenge result contains the user identifier and name for Passkey registration.
let provider = ASAuthorizationPlatformPublicKeyCredentialProvider(relyingPartyIdentifier: "example.com")
let request = provider.createCredentialRegistrationRequest(challenge: result.challenge,
name: result.user.name,
userID: result.user.id)
let controller = ASAuthorizationController(authorizationRequests: [request])
controller.delegate = self
controller.presentationContextProvider = self
// This will display the Passkey sheet for the user to continue with the registration. The outcome of the registration request is provided on the ASAuthorizationControllerDelegate.
controller.performRequests()
// Respond to the request
func authorizationController(controller: controller, didCompleteWithAuthorization: authorization) {
if let credential = authorization.credential as? ASAuthorizationPlatformPublicKeyCredentialRegistration {
// Take steps to handle the registration.
try await client.register(nickname: nickname,
clientDataJSON: credential.rawClientDataJSON,
attestationObject: credential.rawAttestationObject!,
credentialId: credential.credentialID,
token: token)
} else {
// Handle other authentication cases, such as Sign in with Apple.
}
}
此场景适用于之前已使用通行密钥注册其设备的用户。与注册通行密钥类似,它使用 ASAuthorizationControllerDelegate 来处理平台密钥断言请求的结果。
import RelyingPartyKit
// The baseURL is the host of the relying party server.
let client = RelyingPartyClient(baseURL: URL(string: "https://example.com")!)
// First generate a challenge from the relying party server.
let result: CredentialAssertionOptions = try await client.challenge()
// Construct a request to the platform provider with the challenge.
let provider = ASAuthorizationPlatformPublicKeyCredentialProvider(relyingPartyIdentifier: "example.com")
let request = provider.createCredentialAssertionRequest(challenge: result.challenge)
let controller = ASAuthorizationController(authorizationRequests: [request])
controller.delegate = self
controller.presentationContextProvider = self
// This will show the Passkey sheet for the user to continue with the registration and provides the outcome of the registration request on the ASAuthorizationControllerDelegate.
controller.performRequests()
// Respond to the request
func authorizationController(controller: controller, didCompleteWithAuthorization: authorization) {
if let credential = authorization.credential as? ASAuthorizationPlatformPublicKeyCredentialAssertion {
// Take steps to handle the assertion.
let result: Token = try await client.signin(signature: credential.signature,
clientDataJSON: credential.rawClientDataJSON,
authenticatorData: credential.rawAuthenticatorData,
credentialId: credential.credentialID,
userId: credential.userID)
} else {
// Handle other authentication cases, such as Sign in with Apple.
}
}