OktaJWT
概览
此库处理解码和验证由 Okta 授权服务器签发的 JSON Web Token (JWT)。它为 iOS 应用程序提供基于 OIDC 3.1.3.7 的 ID Token 验证的便捷和可定制界面。
安装
Cocoapods
OktaJWT 通过 CocoaPods 提供。要安装,请简单地将以下行添加到您的 Podfile
pod 'OktaJWT'
Swift 包管理器
要通过Swift包管理器将包依赖项添加到您的Xcode项目中,请选择Xcode中的文件
>Swift 包
>添加包依赖项
,并输入仓库URL。
https://github.com/okta/okta-ios-jwt.git
Carthage
要使用Carthage将此SDK集成到您的Xcode项目中,请在其Cartfile
中指定它。
github "okta/okta-ios-jwt"
用法
此库通过扩展JSONWebToken Swift库来支持验证JWT。默认情况下,它将从指定的授权服务器的OAuth 2.0 /keys
端点获取公钥,验证JWT签名,并验证令牌与给定的断言。
首先,创建一个验证选项字典,并实例化OktaJWTValidator
。
let options = [
"issuer": "https://{yourOktaDomain}.com/oauth2/default,
"audience": "{aud}", // More info below
...
] as [String: Any]
let validator = OktaJWTValidator(options)
最后,检查JWT是否有效。
let jwtString = "ey...."
do {
let valid = try validator.isValid(jwtString)
print("Valid: \(valid)")
} catch let error {
print("Error: \(error)")
}
idToken
验证
当使用OpenID Connect作为身份验证机制时,验证从/token
端点返回的idToken
非常重要。为了确保令牌有效,在您的验证选项中包含以下内容:
issuer
:创建idToken
的OAuth 2.0 授权服务器。audience
:您的OpenID Connect应用程序的clientID
。有关更多信息,请参阅实现身份验证 - Auth Code Flow (Okta)。exp
:JWT尚未过期。iat
:JWT不会被发布在未来。nonce
:在授权期间生成的加密字符串。
要了解更多关于验证用例和Okta令牌的信息,请参阅处理OAuth 2.0令牌。
let options = [
"issuer": "https://{yourOktaDomain}.com/oauth2/default",
"audience": "0abc123..",
"exp": true,
"iat": true,
"leeway": 3000, // allow ~5 minutes for clock drift (exp and iat),
"nonce": "1a2b3c4d..."
] as [String: Any]
let validator = OktaJWTValidator(options)
let idToken = "ey..."
do {
let valid = try validator.isValid(idToken)
print("Valid: \(valid)")
} catch let error {
// Misc Error: {error}
}
为确保错误处理正确,您可以捕获、处理并从特定错误中恢复。
do {
let valid = try validator.isValid(idToken)
print("Valid: \(valid)")
} catch OktaJWTVerificationError.malformedJWT {
// Malformed idToken -> "ey.xx"
} catch OktaJWTVerificationError.nonSupportedAlg(let algType) {
// Algorithm type {algType} not supported
} catch OktaJWTVerificationError.invalidIssuer {
// idToken issuer != given issuer
} catch OktaJWTVerificationError.invalidAudience {
// idToken audience != given audience
} catch OktaJWTVerificationError.invalidSignature {
// Invalid signature
} catch OktaJWTVerificationError.expiredJWT {
// idToken expired!
} catch OktaJWTVerificationError.issuedInFuture {
// idToken issued in the future
} catch OktaJWTVerificationError.invalidNonce {
// Invalid nonce
} catch OktaAPIError.noWellKnown {
// Could not retrieve well-known metadata
} catch OktaAPIError.noJWKSEndpoint {
// Unable to capture jwks_uri from well-known
} catch OktaAPIError.noKey {
// Unable to find JWK for Key ID
} catch OktaAPIError.offline {
// Internet connection has not been established (device is offline)
} catch let error {
// Misc Error: {error}
}
自定义声明验证
您可以让验证器声明一组自定义声明,前提是这些声明可以作为一个字符串进行验证。
let options = [
"issuer": "https://{yourOktaDomain}.com/oauth2/default",
"audience": "0abc123..",
"exp": true,
"iat": true,
"preferred_username": "username"
] as [String: Any]
let validator = OktaJWTValidator(options)
let jwtString = "ey..."
do {
let valid = try validator.isValid(jwtString)
print("Valid: \(valid)")
} catch OktaJWTVerificationError.invalidClaim(let claim) {
// Claim {claim} not present
} catch let error {
// Misc Error: {error}
}
高级选项
可选验证器参数
jwk
:传递一个JSON Web Key(JWK),以用于由/keys
端点提供的键之一。RSAKey
:使用现有的RSAKey
let options = [
"issuer": "https://{yourOktaDomain}.com/oauth2/default",
"audience": "0abc123..",
...
] as [String: Any]
let jwtString = "ey..."
// Use custom JWK
let givenJWK = [
"alg": "RS256",
"e": "AQAB",
"n": "kR7T4d_6RrTLQ4rdhdexVsGs6D0UwY9gZotmC7BEMvFovvnB0U3fy7WpmUn3aL9ooUJuDj19h17l3" +
"gENKTaZOLucmLVq6HlK8coukxzk8_zhllrWXXFVwB3TlB-zR2EfWi_FKnyHHrSQ0lb1RfO7wberhy" +
"_FK6n6WA5lCMYVfOGVm3aV6vfAojS7y1QzyimytitCRsOnIW7QmlZ1ZtKcEKb0pGdwSAAj-OSldZL" +
"uLBj9B_t6HMq0xPVNhWgtYGDFNARaCIcvuP236VpGsw3EH4zfeKVMpScHC2j3y5JvMefn_iVgBzW7" +
"9qs6QPbC6Y1_yCJv-ZRfur3Tk92Hq82B4w",
"kid": "someKeyId",
"kty": "RSA",
"use": "sig"
] as [String: Any]
let validator = OktaJWTValidator(options, jwk: givenJWK)
do {
let valid = try validator.isValid(jwtString)
print("Valid: \(valid)")
} catch let error {
// Misc Error: {error}
}
// -- OR --
// Use existing RSAKey
let rsaKey = RSAKey.registeredKeyWithTag("myKeyTag")
let validator = OktaJWTValidator(options, key: rsaKey)
do {
let valid = try validator.isValid(jwtString)
print("Valid: \(valid)")
} catch let error {
// Misc Error: {error}
}
贡献
我们很高兴接受贡献和PR!请参阅贡献指南,了解如何结构化贡献。