IBM Cloud App ID

用于 IBM Cloud App ID 服务的 Swift SDK

IBM Cloud powered Travis Coveralls Codacy Version DownloadsMonthly DownloadsTotal License

GithubWatch GithubStars GithubForks

目录

概要

此 SDK 提供了用于保护 Web 应用程序和 API 端点的 Kitura Credentials 插件。

当使用 WebAppKituraCredentialsPlugin 时,未经身份验证的客户端将被 HTTP 302 重定向到 App ID 服务托管的登录页面(或者,根据配置,直接重定向到身份提供者登录页面)。

阅读官方文档,了解有关开始使用 IBM Cloud App ID 服务的信息。

要求

安装

import PackageDescription

let package = Package(
    ...
    dependencies: [
        .package(url: "https://github.com/ibm-cloud-security/appid-serversdk-swift.git", .upToNextMinor(from: "5.1.0"))
    ]
    .target(
        name: "<Your Target>",
        dependencies: ["IBMCloudAppID"]
    )
)

使用示例

以下是使用此 SDK 保护 Web 应用程序的示例。

使用 WebAppKituraCredentialsPlugin 保护 Web 应用程序

WebAppKituraCredentialsPlugin 基于 OAuth2 authorization_code 授权流程,应供使用浏览器的 Web 应用程序使用。该插件提供了用于轻松实现身份验证和授权流程的工具。 WebAppKituraCredentialsPlugin 提供了检测未经身份验证的访问受保护资源的尝试的机制。 WebAppKituraCredentialsPlugin 将自动将用户的浏览器重定向到身份验证页面。 成功通过身份验证后,用户将被带回到 Web 应用程序的回调 URL (redirectUri),该 URL 将再次使用 WebAppKituraCredentialsPlugin 从 App ID 服务获取访问令牌和身份令牌。 获取这些令牌后,WebAppKituraCredentialsPlugin 会将它们存储在 HTTP 会话的 WebAppKituraCredentialsPlugin.AuthContext 键下。 在可扩展的云环境中,建议将 HTTP 会话持久存储在可扩展的存储(如 Redis)中,以确保它们在多个服务器应用程序实例中可用。

import Kitura
import KituraSession
import Credentials
import SwiftyJSON
import IBMCloudAppID

// Below URLs will be used for App ID OAuth flows
var LOGIN_URL = "/ibm/bluemix/appid/login"
var CALLBACK_URL = "/ibm/bluemix/appid/callback"
var LOGOUT_URL = "/ibm/bluemix/appid/logout"
var LANDING_PAGE_URL = "/index.html"

// Setup Kitura to use session middleware
// Must be configured with proper session storage for production
// environments. See https://github.com/IBM-Swift/Kitura-Session for
// additional documentation
let router = Router()
let session = Session(secret: "Some secret")
router.all(middleware: session)

// Use static resources if required directory
router.all("/", middleware: StaticFileServer(path: "./Tests/IBMCloudAppIDTests/public"))

// Below configuration can be obtained from Service Credentials
// tab in the App ID Dashboard. You're not required to manually provide below
// configuration if your Kitura application runs on IBM Cloud and is bound to the
// App ID service instance. In this case App ID configuration will be obtained
// automatically using VCAP_SERVICES environment variable.
//
// The redirectUri value can be supplied in three ways:
// 1. Manually in new WebAppKituraCredentialsPlugin options
// 2. As environment variable named `redirectUri`
// 3. If none of the above was supplied the App ID SDK will try to retrieve
//    application_uri of the application running on IBM Cloud and append a
//    default suffix "/ibm/bluemix/appid/callback"
let options = [
	"clientId": "{client-id}",
	"secret": "{secret}",
	"tenantId": "{tenant-id}",
	"oauthServerUrl": "{oauth-server-url}",
	"redirectUri": "{app-url}" + CALLBACK_URL
]
let webappKituraCredentialsPlugin = WebAppKituraCredentialsPlugin(options: options)
let kituraCredentials = Credentials()
kituraCredentials.register(plugin: webappKituraCredentialsPlugin)

// Explicit login endpoint
router.get(LOGIN_URL,
		   handler: kituraCredentials.authenticate(credentialsType: webappKituraCredentialsPlugin.name,
												   successRedirect: LANDING_PAGE_URL,
												   failureRedirect: LANDING_PAGE_URL
))

// Callback to finish the authorization process. Will retrieve access and identity tokens from App ID
router.get(CALLBACK_URL,
		   handler: kituraCredentials.authenticate(credentialsType: webappKituraCredentialsPlugin.name,
												   successRedirect: LANDING_PAGE_URL,
												   failureRedirect: LANDING_PAGE_URL
))

// Logout endpoint. Clears authentication information from session
router.get(LOGOUT_URL, handler:  { (request, response, next) in
	kituraCredentials.logOut(request: request)
	webappKituraCredentialsPlugin.logout(request: request)
	_ = try? response.redirect(LANDING_PAGE_URL)
})

// Protected area  using `Credentials` standard `userProfile`
router.get("/protected", handler: kituraCredentials.authenticate(credentialsType: webappKituraCredentialsPlugin.name), { (request, response, next) in
    // check user profile for successful login
    guard let user = request.userProfile else {
        response.status(.unauthorized)
        return next()
    }
    try response.send("Hello \(user.displayName)")
    next()
})

// Protected area using AppID `userIdentity`
router.get("/protected", handler: kituraCredentials.authenticate(credentialsType: webappKituraCredentialsPlugin.name), { (request, response, next) in
    guard let authContextDict = request.session?["APPID_AUTH_CONTEXT"] as? [String: Any],
          let identityTokenPayload = authContextDict["identityTokenPayload"] as? [String: Any],
          let identityTokenData = try? JSONSerialization.data(withJSONObject: identityTokenPayload, options: [])
    else {
        response.status(.unauthorized)
        return next()
    }
    let authContext = AuthorizationContext(idTokenPayload: JSON(data: identityTokenData))
    response.send("Hello \(authContext.userIdentity.displayName)")
    next()
})

// Start the server!
Kitura.addHTTPServer(onPort: 1234, with: router)
Kitura.run()

使用 APIKituraCredentialsPlugin 保护 API 端点

APIKituraCredentialsPlugin 遵循 OAuth Bearer Token 规范,应用于保护后端 API 端点。

当您的 Kitura 后端收到请求时,凭证中间件将检查其授权标头中是否存在 Bearer 令牌,然后根据 App ID 公钥集对其进行验证。 成功后,中间件会将授权上下文和用户配置文件添加到请求中,并将其传递给下一个中间件或您的处理程序。 如果未提供身份令牌,则用户配置文件的字段将为空。

import Kitura
import Credentials
import IBMCloudAppID

// Below configuration can be obtained from Service Credentials
// tab in the App ID Dashboard. You're not required to manually provide below
// configuration if your Kitura application runs on IBM Cloud and is bound to the
// App ID service instance. In this case App ID configuration will be obtained
// automatically using VCAP_SERVICES environment variable.
let options = [
	"oauthServerUrl": "{oauth-server-url}"
]

let apiCredentials = APIKituraCredentialsPlugin(options: options)
let credentials = Credentials()
credentials.register(plugin: apiCredentials)


// Protected area
router.all(middleware: credentials)
router.get("/myName") { (request, response, next) in


    do {
        if let userProfile = request.userProfile  {
            try response.status(.OK).send(userProfile.displayName).end()
        }
    } catch {
        response.status(.internalServerError)
    }
}

// Start the server!
Kitura.addHTTPServer(onPort: 8080, with: router)
Kitura.run()

匿名登录

WebAppKituraCredentialsPlugin 允许用户匿名登录到您的 Web 应用程序,这意味着无需任何凭据。 成功登录后,匿名用户访问令牌将保存在 HTTP 会话中,只要 HTTP 会话保持活动状态,该令牌就可用。 一旦 HTTP 会话被销毁或过期,匿名用户访问令牌也将被销毁。

要允许特定 URL 的匿名登录,请使用以下代码片段中所示的两个配置属性

var LOGIN_ANON_URL = "/ibm/bluemix/appid/loginanon"

let webappKituraCredentialsPlugin = WebAppKituraCredentialsPlugin(options: options)
let kituraCredentialsAnonymous = Credentials(options: [
	WebAppKituraCredentialsPlugin.AllowAnonymousLogin: true,
	WebAppKituraCredentialsPlugin.AllowCreateNewAnonymousUser: true
])
kituraCredentialsAnonymous.register(plugin: webappKituraCredentialsPlugin)

// Explicit anonymous login endpoint
router.get(LOGIN_ANON_URL,
		   handler: kituraCredentialsAnonymous.authenticate(credentialsType: webappKituraCredentialsPlugin.name,
															successRedirect: LANDING_PAGE_URL,
															failureRedirect: LANDING_PAGE_URL
))


router.get(LOGOUT_URL, handler:  { (request, response, next) in
	kituraCredentialsAnonymous.logOut(request: request)
	webappKituraCredentialsPlugin.logout(request: request)
	_ = try? response.redirect(LANDING_PAGE_URL)
})

匿名访问令牌和身份令牌由 App ID SDK 自动保存在 HTTP 会话中。 您可以通过与常规令牌相同的机制从 HTTP 会话中检索它们。 访问令牌和身份令牌将保留在 HTTP 会话中,并将一直使用到令牌或 HTTP 会话过期。

管理用户个人资料

使用 App ID UserProfileManager,您可以创建、删除和检索用户个人资料属性,以及获取有关用户的其他信息。

let userProfileManager = UserProfileManager(options: options)

userProfileManager.getAttribute(accessToken: accessToken, attributeName: "name") { (err, res) in
}

userProfileManager.setAttribute(accessToken: accessToken, attributeName: "name", attributeValue : "abc") { (err, res) in
}

userProfileManager.getAllAttributes(accessToken: accessToken) { (err, res) in
}

userProfileManager.deleteAllAttributes(accessToken: accessToken) { (err, res) in
}

// Retrieve user information by querying the UserInfo endpoint
// If identity token is provided (recommended approach), response is validated against the identity token
userProfileManager.getUserInfo(accessToken: accessToken, identityToken: optionalIdentityToken) { (err, res) in

}

// Retrieve the UserInfo without any validation
userProfileManager.getUserInfo(accessToken: accessToken) { (err, res) in

}

许可证

此软件包包含根据 Apache License, Version 2.0(“许可证”)授权的代码。 您可以在 https://apache.ac.cn/licenses/LICENSE-2.0 获取许可证的副本,也可以查看此软件包中的 LICENSE 文件中的许可证。