From 7b77c54fb6cc3bea6353276b58c277e8aa6b81d7 Mon Sep 17 00:00:00 2001 From: David Jones Date: Tue, 3 Sep 2019 17:18:09 +0100 Subject: [PATCH] fix: Custom subject claim required to be a String (#5) * Add test for UserProfileDelegate * Add documentation and usage examples for custom claims --- README.md | 82 ++++- Sources/CredentialsJWT/CredentialsJWT.swift | 103 +++++- .../CredentialsJWTTests/TestRawRouteJWT.swift | 125 ++++++- docs/Classes.html | 88 ++++- docs/Classes/CredentialsJWT.html | 311 +++++++++++++++--- docs/Extensions.html | 4 +- docs/Extensions/JWT.html | 4 +- docs/Structs.html | 4 +- docs/Structs/CredentialsJWTOptions.html | 4 +- docs/Structs/TypeSafeJWT.html | 4 +- docs/badge.svg | 16 +- .../Contents/Resources/Documents/Classes.html | 88 ++++- .../Documents/Classes/CredentialsJWT.html | 311 +++++++++++++++--- .../Resources/Documents/Extensions.html | 4 +- .../Resources/Documents/Extensions/JWT.html | 4 +- .../Contents/Resources/Documents/Structs.html | 4 +- .../Structs/CredentialsJWTOptions.html | 4 +- .../Documents/Structs/TypeSafeJWT.html | 4 +- .../Contents/Resources/Documents/index.html | 90 ++++- .../Contents/Resources/Documents/search.json | 2 +- .../Contents/Resources/docSet.dsidx | Bin 12288 -> 12288 bytes docs/docsets/CredentialsJWT.tgz | Bin 72330 -> 77181 bytes docs/index.html | 90 ++++- docs/search.json | 2 +- docs/undocumented.json | 8 +- 25 files changed, 1205 insertions(+), 151 deletions(-) diff --git a/README.md b/README.md index 8c8615e..4726e93 100644 --- a/README.md +++ b/README.md @@ -22,14 +22,92 @@ # Kitura-CredentialsJWT -Plugin for the Credentials framework that supports authentication using JWTs. +A package enabling Kitura to authenticate users using [JSON Web Tokens](https://jwt.io/). ## Summary -Plugin for [Kitura-Credentials](https://github.com/IBM-Swift/Kitura-Credentials) framework that supports authentication using [JSON Web Tokens](https://jwt.io/). + +This package provides two facilities: +- `CredentialsJWT`: A plugin for the [Kitura-Credentials](https://github.com/IBM-Swift/Kitura-Credentials) framework that supports JWT (token-based) authentication, +- A `TypeSafeMiddleware` extension for the `JWT` type, enabling it to be used as authentication for Codable routes. ## Swift version The latest version of Kitura-CredentialsJWT requires **Swift 4.0** or newer. You can download this version of the Swift binaries by following this [link](https://swift.org/download/). Compatibility with other Swift versions is not guaranteed. +## Using the `CredentialsJWT` plugin + +This plugin requires that the following HTTP headers are present on a request: +- `X-token-type`: must be `JWT` +- `Authorization`: the JWT string, optionally prefixed with `Bearer`. + +The [Swift-JWT](https://github.com/IBM-Swift/Swift-JWT) library is used to decode the token supplied in the Authorization header. To successfully decode it, you must specify the `Claims` that will be present in the JWT. + +One claim (by default, `sub`) will be used to represent the identity of the bearer. You can choose a different claim by supplying the `subject` option when creating an instance of CredentialsJWT, and you can further customize the resulting `UserProfile` by defining a `UserProfileDelegate`. + +### Usage Example + +To use `CredentialsJWT` using the default options: +```swift +import Credentials +import CredentialsJWT +import SwiftJWT + +// Defines the claims that must be present in a JWT. +struct MyClaims: Claims { + let sub: String +} + +// Defines the method used to verify the signature of a JWT. +let jwtVerifier = .hs256(key: "".data(using: .utf8)!) + +// Create a CredentialsJWT plugin with default options. +let jwtCredentials = CredentialsJWT(verifier: jwtVerifier) + +let authenticationMiddleware = Credentials() +authenticationMiddleware.register(plugin: jwtCredentials) +router.get("/myProtectedRoute", middleware: authenticationMiddleware) +``` + +Following successful authentication, the `UserProfile` will be minimally populated with the two required fields - `id` and `displayName` - both with the value of the JWT's `sub` claim. The `provider` will be set to `JWT`. + +### Usage Example - custom claims + +To customize the name of the identity claim, and further populate the UserProfile fields, specify the `subject` and `userProfileDelegate` options as follows: +```swift +import Credentials +import CredentialsJWT +import SwiftJWT + +// Defines the claims that must be present in a JWT. +struct MyClaims: Claims { + let id: Int + let fullName: String + let email: String +} + +struct MyDelegate: UserProfileDelegate { + func update(userProfile: UserProfile, from dictionary: [String:Any]) { + // `userProfile.id` already contains `id` + userProfile.displayName = dictionary["fullName"]! as! String + let email = UserProfile.UserProfileEmail(value: dictionary["email"]! as! String, type: "home") + userProfile.emails = [email] + } +} + +// Defines the method used to verify the signature of a JWT. +let jwtVerifier = .hs256(key: "".data(using: .utf8)!) + +// Create a CredentialsJWT plugin with default options. +let jwtCredentials = CredentialsJWT(verifier: jwtVerifier, options: [CredentialsJWTOptions.subject: "id", CredentialsJWTOptions.userProfileDelegate: MyDelegate]) + +let authenticationMiddleware = Credentials() +authenticationMiddleware.register(plugin: jwtCredentials) +router.get("/myProtectedRoute", middleware: authenticationMiddleware) +``` +Following successful authentication, the `UserProfile` will be populated as follows: +- `id`: the `id` claim (converted to a String), +- `displayName`: the `fullName` claim, +- `emails`: an array with a single element, representing the `email` claim. + ## Example of JWT authentication for Codable routes A Kitura Codable route can be authenticated using a JWT by using the `JWT` type (defined by [Swift-JWT](https://github.com/IBM-Swift/Swift-JWT)) as a Type-Safe Middleware: diff --git a/Sources/CredentialsJWT/CredentialsJWT.swift b/Sources/CredentialsJWT/CredentialsJWT.swift index 2106ca1..d72c680 100644 --- a/Sources/CredentialsJWT/CredentialsJWT.swift +++ b/Sources/CredentialsJWT/CredentialsJWT.swift @@ -23,20 +23,104 @@ import LoggerAPI // MARK CredentialsJWT -/// Authentication using a JWT. +/** + A plugin for Kitura-Credentials supporting authentication using [JSON Web Tokens](https://jwt.io/). + + This plugin requires that the following HTTP headers are present on a request: + - `X-token-type`: must be `JWT` + - `Authorization`: the JWT string, optionally prefixed with `Bearer`. + + The [Swift-JWT](https://github.com/IBM-Swift/Swift-JWT) library is used to + decode JWT strings. To successfully decode it, you must specify the `Claims` that will + be present in the JWT. One claim (by default, `sub`) will be used to represent the identity of + the bearer. You can choose a different claim by supplying the `subject` option when + creating an instance of CredentialsJWT, and you can further customize the resulting `UserProfile` + by defining a `UserProfileDelegate`. + + ### Usage Example + + To use `CredentialsJWT` using the default options: + ```swift + import Credentials + import CredentialsJWT + import SwiftJWT + + // Defines the claims that must be present in a JWT. + struct MyClaims: Claims { + let sub: String + } + + // Defines the method used to verify the signature of a JWT. + let jwtVerifier = .hs256(key: "".data(using: .utf8)!) + + // Create a CredentialsJWT plugin with default options. + let jwtCredentials = CredentialsJWT(verifier: jwtVerifier) + + let authenticationMiddleware = Credentials() + authenticationMiddleware.register(plugin: jwtCredentials) + router.get("/myProtectedRoute", middleware: authenticationMiddleware) + ``` + + Following successful authentication, the `UserProfile` will be minimally populated with the + two required fields - `id` and `displayName` - both with the value of the JWT's `sub` claim. + The `provider` will be set to `JWT`. + + ### Usage Example - custom claims + + To customize the name of the identity claim, and further populate the UserProfile fields, + specify the `subject` and `userProfileDelegate` options as follows: + ```swift + import Credentials + import CredentialsJWT + import SwiftJWT + + // Defines the claims that must be present in a JWT. + struct MyClaims: Claims { + let id: Int + let fullName: String + let email: String + } + + struct MyDelegate: UserProfileDelegate { + func update(userProfile: UserProfile, from dictionary: [String:Any]) { + // `userProfile.id` already contains `id` + userProfile.displayName = dictionary["fullName"]! as! String + let email = UserProfile.UserProfileEmail(value: dictionary["email"]! as! String, type: "home") + userProfile.emails = [email] + } + } + + // Defines the method used to verify the signature of a JWT. + let jwtVerifier = .hs256(key: "".data(using: .utf8)!) + + // Create a CredentialsJWT plugin with default options. + let jwtCredentials = CredentialsJWT(verifier: jwtVerifier, options: [CredentialsJWTOptions.subject: "id", CredentialsJWTOptions.userProfileDelegate: MyDelegate]) + + let authenticationMiddleware = Credentials() + authenticationMiddleware.register(plugin: jwtCredentials) + router.get("/myProtectedRoute", middleware: authenticationMiddleware) + ``` + Following successful authentication, the `UserProfile` will be populated as follows: + - `id`: the `id` claim (converted to a String), + - `displayName`: the `fullName` claim, + - `emails`: an array with a single element, representing the `email` claim. +*/ public class CredentialsJWT: CredentialsPluginProtocol { - /// The name of the plugin. + /// The name of the plugin: `JWT`. public var name: String { return "JWT" } - /// An indication as to whether the plugin is redirecting or not. + /// An indication as to whether the plugin is redirecting or not. This plugin is not redirecting. public var redirecting: Bool { return false } - /// The time in seconds since the user profile was generated that the access token will be considered valid. + /// The time in seconds since the user profile was generated that the access token will be considered valid + /// and remain in the `usersCache`. + /// + /// By default, this value is `nil`, which means that tokens will be cached indefinitely. public let tokenTimeToLive: TimeInterval? private var delegate: UserProfileDelegate? @@ -50,7 +134,10 @@ public class CredentialsJWT: CredentialsPluginProtocol { /// Token variable used after formatting. var token = "" - /// A delegate for `UserProfile` manipulation. + /// A delegate for `UserProfile` manipulation. Use this to further populate the profile using + /// any fields from the `Claims` that you have defined. + /// + /// This field can be set by passing the `userProfileDelegate` option during initialization. public var userProfileDelegate: UserProfileDelegate? { return delegate } @@ -140,11 +227,13 @@ public class CredentialsJWT: CredentialsPluginProtocol { Log.error("Couldn't decode claims") return onFailure(nil, nil) } - guard let userid = dictionary[subject] as? String else { + // Ensure claims contain the expected subject claim (default `sub`) + guard let subjectClaim = dictionary[subject] else { Log.warning("Unable to create user profile: JWT claims do not contain '\(subject)'") return onFailure(nil, nil) } - + // Convert subject claim value to a String + let userid = String("\(subjectClaim)") let userProfile = UserProfile(id: userid , displayName: userid, provider: "JWT") delegate?.update(userProfile: userProfile, from: dictionary) diff --git a/Tests/CredentialsJWTTests/TestRawRouteJWT.swift b/Tests/CredentialsJWTTests/TestRawRouteJWT.swift index 8339462..9af1696 100644 --- a/Tests/CredentialsJWTTests/TestRawRouteJWT.swift +++ b/Tests/CredentialsJWTTests/TestRawRouteJWT.swift @@ -26,7 +26,8 @@ import Dispatch @testable import CredentialsJWT -// A claims structure that will be used for the tests. The `sub` claim holds the users name. +// A claims structure that will be used for the tests. +// The `sub` claim holds the user's identity. struct TestClaims: Claims, Equatable { var sub: String @@ -38,7 +39,8 @@ struct TestClaims: Claims, Equatable { } } -// An alternate claims structure that will be used for the tests. The `username` holds the users name. +// An alternate claims structure that will be used for the tests. +// The `username` holds the user's identity. struct TestAlternateClaims: Claims, Equatable { var username: String @@ -50,6 +52,32 @@ struct TestAlternateClaims: Claims, Equatable { } } +// A claims structure containing custom claims that should be extracted as part of the +// UserProfile. The `id` holds the user's identity. +struct TestDelegateClaims: Claims, Equatable { + let id: Int + let fullName: String + let email: String + + // Testing requirement: Equatable + static func == (lhs: TestDelegateClaims, rhs: TestDelegateClaims) -> Bool { + return + lhs.id == rhs.id && lhs.fullName == rhs.fullName && lhs.email == rhs.email + } +} + +// A UserProfileDelegate for the route accessed in testDelegateToken. Custom claims +// 'fullName' and 'email' are applied to the UserProfile 'displayName' and 'emails' +// fields. +struct MyDelegate: UserProfileDelegate { + func update(userProfile: UserProfile, from dictionary: [String:Any]) { + // `userProfile.id` already contains `id` + userProfile.displayName = dictionary["fullName"]! as! String + let email = UserProfile.UserProfileEmail(value: dictionary["email"]! as! String, type: "home") + userProfile.emails = [email] + } +} + // Sets option for CredentialsJWT to allow username to be used instead of sub, used in the alternate // credentials tests. let jwtOptions: [String:Any] = [CredentialsJWTOptions.subject: "username"] @@ -58,11 +86,21 @@ let jwtOptions: [String:Any] = [CredentialsJWTOptions.subject: "username"] let jwtCredentials = CredentialsJWT(verifier: .hs256(key: "".data(using: .utf8)!), tokenTimeToLive: 1) let altCredentials = CredentialsJWT(verifier: .hs256(key: "".data(using: .utf8)!), options: jwtOptions) +// Sets options for CredentialsJWT to perform UserProfile manipulation using +// a delegate, making use of custom Claims. +let delegateOptions: [String:Any] = [CredentialsJWTOptions.subject: "id", CredentialsJWTOptions.userProfileDelegate: MyDelegate()] +let delegateCredentials = CredentialsJWT(verifier: .hs256(key: "".data(using: .utf8)!), options: delegateOptions) + class TestRawRouteJWT : XCTestCase { // A User structure that can be passed into the generate jwt route. struct User: Codable { - var name: String + let name: String + let email: String? + init(name: String, email: String? = nil) { + self.name = name + self.email = email + } } // Initiliasting the 3 users names and token variables. @@ -77,6 +115,9 @@ class TestRawRouteJWT : XCTestCase { var altUser = User(name: "Alternate") var jwtString3 = "" + var delegateUser = User(name: "Mr Delegate", email: "mr_delegate@foo.xyz") + var jwtString4 = "" + // Key used in generation and decoding of JWT strings. let key = "".data(using: .utf8) @@ -183,6 +224,31 @@ class TestRawRouteJWT : XCTestCase { } }) } + + // User 4 JWT created. User 4 uses the delegate test claims. + performServerTest(router: router) { expectation in + self.performRequest(method: "post", path: "/generateRawJwtDelegate", contentType: "application/json", callback: { response in + do { + guard let body = try response?.readString() else { + XCTFail("Couldn't read response") + return expectation.fulfill() + } + self.jwtString4 = body + print(self.jwtString4) + } catch { + XCTFail("Couldn't read string from response") + expectation.fulfill() + } + expectation.fulfill() + }, requestModifier: { request in + do { + try request.write(from: JSONEncoder().encode(self.delegateUser)) + } catch { + XCTFail("Failed to send data") + expectation.fulfill() + } + }) + } } // Tests that when a correct token is supplied a valid UserProfile is created. @@ -231,6 +297,32 @@ class TestRawRouteJWT : XCTestCase { } } + // Tests that when a JWT is supplied that contains custom claims, to a route + // whose CredentialsJWT is configured with a suitable delegate, the profile + // contains the values of those custom claims (fullName and email). + func testDelegateToken() { + performServerTest(router: router) { expectation in + self.performRequest(method: "get", path: "/rawTokenAuthDelegate", callback: { response in + XCTAssertNotNil(response, "ERROR!!! ClientRequest response object was nil") + XCTAssertEqual(response?.statusCode, HTTPStatusCode.OK, "HTTP Status code was \(String(describing: response?.statusCode))") + do { + guard let body = try response?.readString() else { + XCTFail("No response body") + return expectation.fulfill() + } + let profile = body + let expectedProfile = "Mr Delegate,mr_delegate@foo.xyz" + XCTAssertEqual(profile, expectedProfile) + //TODO + } catch { + XCTFail("Could not decode response: \(error)") + expectation.fulfill() + } + expectation.fulfill() + }, headers: ["X-Token-Type" : "JWT", "Authorization" : "Bearer " + self.jwtString4]) + } + } + // Tests that when an incorrect token is supplied an invalid token is supplied, user is unauthorized. func testInvalidToken() { performServerTest(router: router) { expectation in @@ -417,10 +509,12 @@ class TestRawRouteJWT : XCTestCase { let jwtSigner = JWTSigner.hs256(key: key!) let tokenCredentials = Credentials() let altTokenCredentials = Credentials() + let delegateTokenCredentials = Credentials() tokenCredentials.register(plugin: jwtCredentials) tokenCredentials.register(plugin: CredentialsGoogleToken()) altTokenCredentials.register(plugin: altCredentials) + delegateTokenCredentials.register(plugin: delegateCredentials) router.get("/rawtokenauth", middleware: tokenCredentials) router.get("/rawtokenauth") { request, response, next in @@ -446,6 +540,20 @@ class TestRawRouteJWT : XCTestCase { next() } + router.get("/rawTokenAuthDelegate", middleware: delegateTokenCredentials) + router.get("/rawTokenAuthDelegate") { request, response, next in + guard let userProfile = request.userProfile else { + Log.verbose("Failed raw token authentication") + return try response.status(.unauthorized).end() + } + guard let email = userProfile.emails?.first?.value else { + Log.verbose("UserProfile e-mail was not populated") + return try response.status(.unauthorized).end() + } + response.send("\(userProfile.displayName),\(email)") + next() + } + // Route that generates a jwt from a given User's name. router.post("/generaterawjwt") { request, response, next in let credentials = try request.read(as: User.self) @@ -468,6 +576,17 @@ class TestRawRouteJWT : XCTestCase { next() } + // Route that generates a jwt from a given User's name. + router.post("/generateRawJwtDelegate") { request, response, next in + let credentials = try request.read(as: User.self) + // Users credentials are authenticated + let myClaims = TestDelegateClaims(id: 123, fullName: credentials.name, email: credentials.email!) + var myJWT = JWT(claims: myClaims) + let signedJWT = try myJWT.sign(using: jwtSigner) + response.send(signedJWT) + next() + } + return router } diff --git a/docs/Classes.html b/docs/Classes.html index 18477da..8eacff9 100644 --- a/docs/Classes.html +++ b/docs/Classes.html @@ -23,7 +23,7 @@ CredentialsJWT Docs - (94% documented) + (100% documented)

@@ -106,7 +106,89 @@

Classes

-

Undocumented

+

A plugin for Kitura-Credentials supporting authentication using JSON Web Tokens.

+ +

This plugin requires that the following HTTP headers are present on a request:

+ +
    +
  • X-token-type: must be JWT
  • +
  • Authorization: the JWT string, optionally prefixed with Bearer.
  • +
+ +

The Swift-JWT library is used to +decode JWT strings. To successfully decode it, you must specify the Claims that will +be present in the JWT. One claim (by default, sub) will be used to represent the identity of +the bearer. You can choose a different claim by supplying the subject option when +creating an instance of CredentialsJWT, and you can further customize the resulting UserProfile +by defining a UserProfileDelegate.

+

 Usage Example

+ +

To use CredentialsJWT using the default options:

+
import Credentials
+import CredentialsJWT
+import SwiftJWT
+
+// Defines the claims that must be present in a JWT.
+struct MyClaims: Claims {
+    let sub: String
+}
+
+// Defines the method used to verify the signature of a JWT.
+let jwtVerifier = .hs256(key: "<PrivateKey>".data(using: .utf8)!)
+
+// Create a CredentialsJWT plugin with default options.
+let jwtCredentials = CredentialsJWT<MyClaims>(verifier: jwtVerifier)
+
+let authenticationMiddleware = Credentials()
+authenticationMiddleware.register(plugin: jwtCredentials)
+router.get("/myProtectedRoute", middleware: authenticationMiddleware)
+
+ +

Following successful authentication, the UserProfile will be minimally populated with the +two required fields - id and displayName - both with the value of the JWT’s sub claim. +The provider will be set to JWT.

+

Usage Example - custom claims

+ +

To customize the name of the identity claim, and further populate the UserProfile fields, +specify the subject and userProfileDelegate options as follows:

+
import Credentials
+import CredentialsJWT
+import SwiftJWT
+
+// Defines the claims that must be present in a JWT.
+struct MyClaims: Claims {
+    let id: Int
+    let fullName: String
+    let email: String
+}
+
+struct MyDelegate: UserProfileDelegate {
+    func update(userProfile: UserProfile, from dictionary: [String:Any]) {
+        // `userProfile.id` already contains `id`
+        userProfile.displayName = dictionary["fullName"]! as! String
+        let email = UserProfile.UserProfileEmail(value: dictionary["email"]! as! String, type: "home")
+        userProfile.emails = [email]
+    }
+}
+
+// Defines the method used to verify the signature of a JWT.
+let jwtVerifier = .hs256(key: "<PrivateKey>".data(using: .utf8)!)
+
+// Create a CredentialsJWT plugin with default options.
+let jwtCredentials = CredentialsJWT<MyClaims>(verifier: jwtVerifier, options: [CredentialsJWTOptions.subject: "id", CredentialsJWTOptions.userProfileDelegate: MyDelegate])
+
+let authenticationMiddleware = Credentials()
+authenticationMiddleware.register(plugin: jwtCredentials)
+router.get("/myProtectedRoute", middleware: authenticationMiddleware)
+
+ +

Following successful authentication, the UserProfile will be populated as follows:

+ +
    +
  • id: the id claim (converted to a String),
  • +
  • displayName: the fullName claim,
  • +
  • emails: an array with a single element, representing the email claim.
  • +
See more
@@ -129,7 +211,7 @@

Declaration

diff --git a/docs/Classes/CredentialsJWT.html b/docs/Classes/CredentialsJWT.html index f0741d3..74b9534 100644 --- a/docs/Classes/CredentialsJWT.html +++ b/docs/Classes/CredentialsJWT.html @@ -23,7 +23,7 @@ CredentialsJWT Docs - (94% documented) + (100% documented)

@@ -90,7 +90,89 @@

CredentialsJWT

-

Undocumented

+

A plugin for Kitura-Credentials supporting authentication using JSON Web Tokens.

+ +

This plugin requires that the following HTTP headers are present on a request:

+ +
    +
  • X-token-type: must be JWT
  • +
  • Authorization: the JWT string, optionally prefixed with Bearer.
  • +
+ +

The Swift-JWT library is used to +decode JWT strings. To successfully decode it, you must specify the Claims that will +be present in the JWT. One claim (by default, sub) will be used to represent the identity of +the bearer. You can choose a different claim by supplying the subject option when +creating an instance of CredentialsJWT, and you can further customize the resulting UserProfile +by defining a UserProfileDelegate.

+

 Usage Example

+ +

To use CredentialsJWT using the default options:

+
import Credentials
+import CredentialsJWT
+import SwiftJWT
+
+// Defines the claims that must be present in a JWT.
+struct MyClaims: Claims {
+    let sub: String
+}
+
+// Defines the method used to verify the signature of a JWT.
+let jwtVerifier = .hs256(key: "<PrivateKey>".data(using: .utf8)!)
+
+// Create a CredentialsJWT plugin with default options.
+let jwtCredentials = CredentialsJWT<MyClaims>(verifier: jwtVerifier)
+
+let authenticationMiddleware = Credentials()
+authenticationMiddleware.register(plugin: jwtCredentials)
+router.get("/myProtectedRoute", middleware: authenticationMiddleware)
+
+ +

Following successful authentication, the UserProfile will be minimally populated with the +two required fields - id and displayName - both with the value of the JWT’s sub claim. +The provider will be set to JWT.

+

Usage Example - custom claims

+ +

To customize the name of the identity claim, and further populate the UserProfile fields, +specify the subject and userProfileDelegate options as follows:

+
import Credentials
+import CredentialsJWT
+import SwiftJWT
+
+// Defines the claims that must be present in a JWT.
+struct MyClaims: Claims {
+    let id: Int
+    let fullName: String
+    let email: String
+}
+
+struct MyDelegate: UserProfileDelegate {
+    func update(userProfile: UserProfile, from dictionary: [String:Any]) {
+        // `userProfile.id` already contains `id`
+        userProfile.displayName = dictionary["fullName"]! as! String
+        let email = UserProfile.UserProfileEmail(value: dictionary["email"]! as! String, type: "home")
+        userProfile.emails = [email]
+    }
+}
+
+// Defines the method used to verify the signature of a JWT.
+let jwtVerifier = .hs256(key: "<PrivateKey>".data(using: .utf8)!)
+
+// Create a CredentialsJWT plugin with default options.
+let jwtCredentials = CredentialsJWT<MyClaims>(verifier: jwtVerifier, options: [CredentialsJWTOptions.subject: "id", CredentialsJWTOptions.userProfileDelegate: MyDelegate])
+
+let authenticationMiddleware = Credentials()
+authenticationMiddleware.register(plugin: jwtCredentials)
+router.get("/myProtectedRoute", middleware: authenticationMiddleware)
+
+ +

Following successful authentication, the UserProfile will be populated as follows:

+ +
    +
  • id: the id claim (converted to a String),
  • +
  • displayName: the fullName claim,
  • +
  • emails: an array with a single element, representing the email claim.
  • +
@@ -102,35 +184,9 @@

CredentialsJWT

  • - - - usersCache - -
    -
    -
    -
    -
    -
    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public var usersCache: NSCache<NSString, BaseCacheElement>?
    - -
    -
    -
    -
    -
  • -
  • -
    - - + - name + name
    @@ -138,7 +194,8 @@

    Declaration

    - +

    The name of the plugin: JWT.

    +

    Declaration

    @@ -154,9 +211,9 @@

    Declaration

  • @@ -164,7 +221,8 @@

    Declaration

    - +

    An indication as to whether the plugin is redirecting or not. This plugin is not redirecting.

    +

    Declaration

    @@ -190,7 +248,10 @@

    Declaration

    -

    The time in seconds since the user profile was generated that the access token will be considered valid.

    +

    The time in seconds since the user profile was generated that the access token will be considered valid +and remain in the usersCache.

    + +

    By default, this value is nil, which means that tokens will be cached indefinitely.

    @@ -207,9 +268,9 @@

    Declaration

  • @@ -217,7 +278,11 @@

    Declaration

    - +

    A delegate for UserProfile manipulation. Use this to further populate the profile using +any fields from the Claims that you have defined.

    + +

    This field can be set by passing the userProfileDelegate option during initialization.

    +

    Declaration

    @@ -243,7 +308,18 @@

    Declaration

    -

    Initialize a CredentialsGoogleToken instance.

    +

    Initialize a CredentialsJWT instance. Upon first receipt, a JWT will be verified to ensure the signature is valid, +and that the JWT’s claims can be decoded into an instance of your Claims type. The claims are used to generate +a UserProfile. The profile will be cached against the token, so that future receipts of the same token are more +efficient. The time a token is cached for can be configured.

    + +

    One claim (by default, sub) will be considered the ‘identity’ of the bearer, and will be used to populate the +id and displayName properties of the profile. This claim can be customized by setting the subject option +to the name of the appropriate claim in your Claims.

    + +

    If you require additional claims to appear as properties of the profile, supply the userProfileDelegate option. +The UserProfileDelegate will be given a dictionary containing the claims of the JWT from which it can populate +the profile.

    @@ -258,6 +334,18 @@

    Declaration

    Parameters

    + + + + + + + + @@ -279,9 +379,36 @@

    Parameters

  • - + + + usersCache + +
    +
    +
    +
    +
    +
    +

    User profile cache.

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public var usersCache: NSCache<NSString, BaseCacheElement>?
    + +
    +
    +
    +
    +
  • +
  • +
    @@ -289,7 +416,8 @@

    Parameters

    - +

    Authenticate incoming request using a JWT.

    +

    Declaration

    @@ -303,6 +431,101 @@

    Declaration

    +
    +

    Parameters

    +
  • + + verifier + + +
    +

    Determines the key and algorithm used to verify the received JWT.

    +
    +
    @@ -266,7 +354,19 @@

    Parameters

    -

    A dictionary of plugin specific options. The keys are defined in CredentialsGoogleOptions.

    +

    A dictionary of plugin specific options. The keys are defined in CredentialsJWTOptions.

    +
    +
    + + tokenTimeToLive + + +
    +

    How long the token should remain cached (in seconds). The default is nil, which means the token will be cached indefinitely.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + request + + +
    +

    The RouterRequest object used to get information + about the request.

    +
    +
    + + response + + +
    +

    The RouterResponse object used to respond to the + request.

    +
    +
    + + options + + +
    +

    The dictionary of plugin specific options.

    +
    +
    + + onSuccess + + +
    +

    The closure to invoke in the case of successful authentication.

    +
    +
    + + onFailure + + +
    +

    The closure to invoke in the case of an authentication failure.

    +
    +
    + + onPass + + +
    +

    The closure to invoke when the plugin doesn’t recognize the + authentication token in the request.

    +
    +
    + + inProgress + + +
    +

    The closure to invoke to cause a redirect to the login page in the + case of redirecting authentication.

    +
    +
    +
  • @@ -314,7 +537,7 @@

    Declaration

    diff --git a/docs/Extensions.html b/docs/Extensions.html index 00779b3..d86e29f 100644 --- a/docs/Extensions.html +++ b/docs/Extensions.html @@ -23,7 +23,7 @@ CredentialsJWT Docs - (94% documented) + (100% documented)

    @@ -128,7 +128,7 @@

    Declaration

    diff --git a/docs/Extensions/JWT.html b/docs/Extensions/JWT.html index 4c64d8c..1d5ee10 100644 --- a/docs/Extensions/JWT.html +++ b/docs/Extensions/JWT.html @@ -23,7 +23,7 @@ CredentialsJWT Docs - (94% documented) + (100% documented)

    @@ -189,7 +189,7 @@

    Declaration

    diff --git a/docs/Structs.html b/docs/Structs.html index 18675ff..b1fcfa6 100644 --- a/docs/Structs.html +++ b/docs/Structs.html @@ -23,7 +23,7 @@ CredentialsJWT Docs - (94% documented) + (100% documented)

    @@ -163,7 +163,7 @@

    Declaration

  • diff --git a/docs/Structs/CredentialsJWTOptions.html b/docs/Structs/CredentialsJWTOptions.html index 113c9bc..994c039 100644 --- a/docs/Structs/CredentialsJWTOptions.html +++ b/docs/Structs/CredentialsJWTOptions.html @@ -23,7 +23,7 @@ CredentialsJWT Docs - (94% documented) + (100% documented)

    @@ -161,7 +161,7 @@

    Declaration

    diff --git a/docs/Structs/TypeSafeJWT.html b/docs/Structs/TypeSafeJWT.html index c1d0762..dff828d 100644 --- a/docs/Structs/TypeSafeJWT.html +++ b/docs/Structs/TypeSafeJWT.html @@ -23,7 +23,7 @@ CredentialsJWT Docs - (94% documented) + (100% documented)

    @@ -191,7 +191,7 @@

    Declaration

    diff --git a/docs/badge.svg b/docs/badge.svg index a5fd08d..a096fec 100644 --- a/docs/badge.svg +++ b/docs/badge.svg @@ -1,15 +1,15 @@ - + - + - - + + @@ -18,11 +18,11 @@ documentation - - 94% + + 100% - - 94% + + 100% diff --git a/docs/docsets/CredentialsJWT.docset/Contents/Resources/Documents/Classes.html b/docs/docsets/CredentialsJWT.docset/Contents/Resources/Documents/Classes.html index 18477da..8eacff9 100644 --- a/docs/docsets/CredentialsJWT.docset/Contents/Resources/Documents/Classes.html +++ b/docs/docsets/CredentialsJWT.docset/Contents/Resources/Documents/Classes.html @@ -23,7 +23,7 @@ CredentialsJWT Docs - (94% documented) + (100% documented)

    @@ -106,7 +106,89 @@

    Classes

    -

    Undocumented

    +

    A plugin for Kitura-Credentials supporting authentication using JSON Web Tokens.

    + +

    This plugin requires that the following HTTP headers are present on a request:

    + +
      +
    • X-token-type: must be JWT
    • +
    • Authorization: the JWT string, optionally prefixed with Bearer.
    • +
    + +

    The Swift-JWT library is used to +decode JWT strings. To successfully decode it, you must specify the Claims that will +be present in the JWT. One claim (by default, sub) will be used to represent the identity of +the bearer. You can choose a different claim by supplying the subject option when +creating an instance of CredentialsJWT, and you can further customize the resulting UserProfile +by defining a UserProfileDelegate.

    +

     Usage Example

    + +

    To use CredentialsJWT using the default options:

    +
    import Credentials
    +import CredentialsJWT
    +import SwiftJWT
    +
    +// Defines the claims that must be present in a JWT.
    +struct MyClaims: Claims {
    +    let sub: String
    +}
    +
    +// Defines the method used to verify the signature of a JWT.
    +let jwtVerifier = .hs256(key: "<PrivateKey>".data(using: .utf8)!)
    +
    +// Create a CredentialsJWT plugin with default options.
    +let jwtCredentials = CredentialsJWT<MyClaims>(verifier: jwtVerifier)
    +
    +let authenticationMiddleware = Credentials()
    +authenticationMiddleware.register(plugin: jwtCredentials)
    +router.get("/myProtectedRoute", middleware: authenticationMiddleware)
    +
    + +

    Following successful authentication, the UserProfile will be minimally populated with the +two required fields - id and displayName - both with the value of the JWT’s sub claim. +The provider will be set to JWT.

    +

    Usage Example - custom claims

    + +

    To customize the name of the identity claim, and further populate the UserProfile fields, +specify the subject and userProfileDelegate options as follows:

    +
    import Credentials
    +import CredentialsJWT
    +import SwiftJWT
    +
    +// Defines the claims that must be present in a JWT.
    +struct MyClaims: Claims {
    +    let id: Int
    +    let fullName: String
    +    let email: String
    +}
    +
    +struct MyDelegate: UserProfileDelegate {
    +    func update(userProfile: UserProfile, from dictionary: [String:Any]) {
    +        // `userProfile.id` already contains `id`
    +        userProfile.displayName = dictionary["fullName"]! as! String
    +        let email = UserProfile.UserProfileEmail(value: dictionary["email"]! as! String, type: "home")
    +        userProfile.emails = [email]
    +    }
    +}
    +
    +// Defines the method used to verify the signature of a JWT.
    +let jwtVerifier = .hs256(key: "<PrivateKey>".data(using: .utf8)!)
    +
    +// Create a CredentialsJWT plugin with default options.
    +let jwtCredentials = CredentialsJWT<MyClaims>(verifier: jwtVerifier, options: [CredentialsJWTOptions.subject: "id", CredentialsJWTOptions.userProfileDelegate: MyDelegate])
    +
    +let authenticationMiddleware = Credentials()
    +authenticationMiddleware.register(plugin: jwtCredentials)
    +router.get("/myProtectedRoute", middleware: authenticationMiddleware)
    +
    + +

    Following successful authentication, the UserProfile will be populated as follows:

    + +
      +
    • id: the id claim (converted to a String),
    • +
    • displayName: the fullName claim,
    • +
    • emails: an array with a single element, representing the email claim.
    • +
    See more
    @@ -129,7 +211,7 @@

    Declaration

    diff --git a/docs/docsets/CredentialsJWT.docset/Contents/Resources/Documents/Classes/CredentialsJWT.html b/docs/docsets/CredentialsJWT.docset/Contents/Resources/Documents/Classes/CredentialsJWT.html index f0741d3..74b9534 100644 --- a/docs/docsets/CredentialsJWT.docset/Contents/Resources/Documents/Classes/CredentialsJWT.html +++ b/docs/docsets/CredentialsJWT.docset/Contents/Resources/Documents/Classes/CredentialsJWT.html @@ -23,7 +23,7 @@ CredentialsJWT Docs - (94% documented) + (100% documented)

    @@ -90,7 +90,89 @@

    CredentialsJWT

    -

    Undocumented

    +

    A plugin for Kitura-Credentials supporting authentication using JSON Web Tokens.

    + +

    This plugin requires that the following HTTP headers are present on a request:

    + +
      +
    • X-token-type: must be JWT
    • +
    • Authorization: the JWT string, optionally prefixed with Bearer.
    • +
    + +

    The Swift-JWT library is used to +decode JWT strings. To successfully decode it, you must specify the Claims that will +be present in the JWT. One claim (by default, sub) will be used to represent the identity of +the bearer. You can choose a different claim by supplying the subject option when +creating an instance of CredentialsJWT, and you can further customize the resulting UserProfile +by defining a UserProfileDelegate.

    +

     Usage Example

    + +

    To use CredentialsJWT using the default options:

    +
    import Credentials
    +import CredentialsJWT
    +import SwiftJWT
    +
    +// Defines the claims that must be present in a JWT.
    +struct MyClaims: Claims {
    +    let sub: String
    +}
    +
    +// Defines the method used to verify the signature of a JWT.
    +let jwtVerifier = .hs256(key: "<PrivateKey>".data(using: .utf8)!)
    +
    +// Create a CredentialsJWT plugin with default options.
    +let jwtCredentials = CredentialsJWT<MyClaims>(verifier: jwtVerifier)
    +
    +let authenticationMiddleware = Credentials()
    +authenticationMiddleware.register(plugin: jwtCredentials)
    +router.get("/myProtectedRoute", middleware: authenticationMiddleware)
    +
    + +

    Following successful authentication, the UserProfile will be minimally populated with the +two required fields - id and displayName - both with the value of the JWT’s sub claim. +The provider will be set to JWT.

    +

    Usage Example - custom claims

    + +

    To customize the name of the identity claim, and further populate the UserProfile fields, +specify the subject and userProfileDelegate options as follows:

    +
    import Credentials
    +import CredentialsJWT
    +import SwiftJWT
    +
    +// Defines the claims that must be present in a JWT.
    +struct MyClaims: Claims {
    +    let id: Int
    +    let fullName: String
    +    let email: String
    +}
    +
    +struct MyDelegate: UserProfileDelegate {
    +    func update(userProfile: UserProfile, from dictionary: [String:Any]) {
    +        // `userProfile.id` already contains `id`
    +        userProfile.displayName = dictionary["fullName"]! as! String
    +        let email = UserProfile.UserProfileEmail(value: dictionary["email"]! as! String, type: "home")
    +        userProfile.emails = [email]
    +    }
    +}
    +
    +// Defines the method used to verify the signature of a JWT.
    +let jwtVerifier = .hs256(key: "<PrivateKey>".data(using: .utf8)!)
    +
    +// Create a CredentialsJWT plugin with default options.
    +let jwtCredentials = CredentialsJWT<MyClaims>(verifier: jwtVerifier, options: [CredentialsJWTOptions.subject: "id", CredentialsJWTOptions.userProfileDelegate: MyDelegate])
    +
    +let authenticationMiddleware = Credentials()
    +authenticationMiddleware.register(plugin: jwtCredentials)
    +router.get("/myProtectedRoute", middleware: authenticationMiddleware)
    +
    + +

    Following successful authentication, the UserProfile will be populated as follows:

    + +
      +
    • id: the id claim (converted to a String),
    • +
    • displayName: the fullName claim,
    • +
    • emails: an array with a single element, representing the email claim.
    • +
    @@ -102,35 +184,9 @@

    CredentialsJWT

  • - - - usersCache - -
    -
    -
    -
    -
    -
    - -
    -
    -

    Declaration

    -
    -

    Swift

    -
    public var usersCache: NSCache<NSString, BaseCacheElement>?
    - -
    -
    -
    -
    -
  • -
  • -
    - - + - name + name
    @@ -138,7 +194,8 @@

    Declaration

    - +

    The name of the plugin: JWT.

    +

    Declaration

    @@ -154,9 +211,9 @@

    Declaration

  • @@ -164,7 +221,8 @@

    Declaration

    - +

    An indication as to whether the plugin is redirecting or not. This plugin is not redirecting.

    +

    Declaration

    @@ -190,7 +248,10 @@

    Declaration

    -

    The time in seconds since the user profile was generated that the access token will be considered valid.

    +

    The time in seconds since the user profile was generated that the access token will be considered valid +and remain in the usersCache.

    + +

    By default, this value is nil, which means that tokens will be cached indefinitely.

    @@ -207,9 +268,9 @@

    Declaration

  • @@ -217,7 +278,11 @@

    Declaration

    - +

    A delegate for UserProfile manipulation. Use this to further populate the profile using +any fields from the Claims that you have defined.

    + +

    This field can be set by passing the userProfileDelegate option during initialization.

    +

    Declaration

    @@ -243,7 +308,18 @@

    Declaration

    -

    Initialize a CredentialsGoogleToken instance.

    +

    Initialize a CredentialsJWT instance. Upon first receipt, a JWT will be verified to ensure the signature is valid, +and that the JWT’s claims can be decoded into an instance of your Claims type. The claims are used to generate +a UserProfile. The profile will be cached against the token, so that future receipts of the same token are more +efficient. The time a token is cached for can be configured.

    + +

    One claim (by default, sub) will be considered the ‘identity’ of the bearer, and will be used to populate the +id and displayName properties of the profile. This claim can be customized by setting the subject option +to the name of the appropriate claim in your Claims.

    + +

    If you require additional claims to appear as properties of the profile, supply the userProfileDelegate option. +The UserProfileDelegate will be given a dictionary containing the claims of the JWT from which it can populate +the profile.

    @@ -258,6 +334,18 @@

    Declaration

    Parameters

    + + + + + + + + @@ -279,9 +379,36 @@

    Parameters

  • - + + + usersCache + +
    +
    +
    +
    +
    +
    +

    User profile cache.

    + +
    +
    +

    Declaration

    +
    +

    Swift

    +
    public var usersCache: NSCache<NSString, BaseCacheElement>?
    + +
    +
    +
    +
    +
  • +
  • +
    @@ -289,7 +416,8 @@

    Parameters

    - +

    Authenticate incoming request using a JWT.

    +

    Declaration

    @@ -303,6 +431,101 @@

    Declaration

    +
    +

    Parameters

    +
  • + + verifier + + +
    +

    Determines the key and algorithm used to verify the received JWT.

    +
    +
    @@ -266,7 +354,19 @@

    Parameters

    -

    A dictionary of plugin specific options. The keys are defined in CredentialsGoogleOptions.

    +

    A dictionary of plugin specific options. The keys are defined in CredentialsJWTOptions.

    +
    +
    + + tokenTimeToLive + + +
    +

    How long the token should remain cached (in seconds). The default is nil, which means the token will be cached indefinitely.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + request + + +
    +

    The RouterRequest object used to get information + about the request.

    +
    +
    + + response + + +
    +

    The RouterResponse object used to respond to the + request.

    +
    +
    + + options + + +
    +

    The dictionary of plugin specific options.

    +
    +
    + + onSuccess + + +
    +

    The closure to invoke in the case of successful authentication.

    +
    +
    + + onFailure + + +
    +

    The closure to invoke in the case of an authentication failure.

    +
    +
    + + onPass + + +
    +

    The closure to invoke when the plugin doesn’t recognize the + authentication token in the request.

    +
    +
    + + inProgress + + +
    +

    The closure to invoke to cause a redirect to the login page in the + case of redirecting authentication.

    +
    +
    +
  • @@ -314,7 +537,7 @@

    Declaration

    diff --git a/docs/docsets/CredentialsJWT.docset/Contents/Resources/Documents/Extensions.html b/docs/docsets/CredentialsJWT.docset/Contents/Resources/Documents/Extensions.html index 00779b3..d86e29f 100644 --- a/docs/docsets/CredentialsJWT.docset/Contents/Resources/Documents/Extensions.html +++ b/docs/docsets/CredentialsJWT.docset/Contents/Resources/Documents/Extensions.html @@ -23,7 +23,7 @@ CredentialsJWT Docs - (94% documented) + (100% documented)

    @@ -128,7 +128,7 @@

    Declaration

    diff --git a/docs/docsets/CredentialsJWT.docset/Contents/Resources/Documents/Extensions/JWT.html b/docs/docsets/CredentialsJWT.docset/Contents/Resources/Documents/Extensions/JWT.html index 4c64d8c..1d5ee10 100644 --- a/docs/docsets/CredentialsJWT.docset/Contents/Resources/Documents/Extensions/JWT.html +++ b/docs/docsets/CredentialsJWT.docset/Contents/Resources/Documents/Extensions/JWT.html @@ -23,7 +23,7 @@ CredentialsJWT Docs - (94% documented) + (100% documented)

    @@ -189,7 +189,7 @@

    Declaration

    diff --git a/docs/docsets/CredentialsJWT.docset/Contents/Resources/Documents/Structs.html b/docs/docsets/CredentialsJWT.docset/Contents/Resources/Documents/Structs.html index 18675ff..b1fcfa6 100644 --- a/docs/docsets/CredentialsJWT.docset/Contents/Resources/Documents/Structs.html +++ b/docs/docsets/CredentialsJWT.docset/Contents/Resources/Documents/Structs.html @@ -23,7 +23,7 @@ CredentialsJWT Docs - (94% documented) + (100% documented)

    @@ -163,7 +163,7 @@

    Declaration

  • diff --git a/docs/docsets/CredentialsJWT.docset/Contents/Resources/Documents/Structs/CredentialsJWTOptions.html b/docs/docsets/CredentialsJWT.docset/Contents/Resources/Documents/Structs/CredentialsJWTOptions.html index 113c9bc..994c039 100644 --- a/docs/docsets/CredentialsJWT.docset/Contents/Resources/Documents/Structs/CredentialsJWTOptions.html +++ b/docs/docsets/CredentialsJWT.docset/Contents/Resources/Documents/Structs/CredentialsJWTOptions.html @@ -23,7 +23,7 @@ CredentialsJWT Docs - (94% documented) + (100% documented)

    @@ -161,7 +161,7 @@

    Declaration

    diff --git a/docs/docsets/CredentialsJWT.docset/Contents/Resources/Documents/Structs/TypeSafeJWT.html b/docs/docsets/CredentialsJWT.docset/Contents/Resources/Documents/Structs/TypeSafeJWT.html index c1d0762..dff828d 100644 --- a/docs/docsets/CredentialsJWT.docset/Contents/Resources/Documents/Structs/TypeSafeJWT.html +++ b/docs/docsets/CredentialsJWT.docset/Contents/Resources/Documents/Structs/TypeSafeJWT.html @@ -23,7 +23,7 @@ CredentialsJWT Docs - (94% documented) + (100% documented)

    @@ -191,7 +191,7 @@

    Declaration

    diff --git a/docs/docsets/CredentialsJWT.docset/Contents/Resources/Documents/index.html b/docs/docsets/CredentialsJWT.docset/Contents/Resources/Documents/index.html index f6f5606..405cc3b 100644 --- a/docs/docsets/CredentialsJWT.docset/Contents/Resources/Documents/index.html +++ b/docs/docsets/CredentialsJWT.docset/Contents/Resources/Documents/index.html @@ -22,7 +22,7 @@ CredentialsJWT Docs - (94% documented) + (100% documented)

    @@ -105,13 +105,95 @@

    Kitura-CredentialsJWT

    -

    Plugin for the Credentials framework that supports authentication using JWTs.

    +

    A package enabling Kitura to authenticate users using JSON Web Tokens.

    Summary

    -

    Plugin for Kitura-Credentials framework that supports authentication using JSON Web Tokens.

    +

    This package provides two facilities:

    + +
      +
    • CredentialsJWT: A plugin for the Kitura-Credentials framework that supports JWT (token-based) authentication,
    • +
    • A TypeSafeMiddleware extension for the JWT type, enabling it to be used as authentication for Codable routes.
    • +

    Swift version

    The latest version of Kitura-CredentialsJWT requires Swift 4.0 or newer. You can download this version of the Swift binaries by following this link. Compatibility with other Swift versions is not guaranteed.

    +

    Using the CredentialsJWT plugin

    + +

    This plugin requires that the following HTTP headers are present on a request:

    + +
      +
    • X-token-type: must be JWT
    • +
    • Authorization: the JWT string, optionally prefixed with Bearer.
    • +
    + +

    The Swift-JWT library is used to decode the token supplied in the Authorization header. To successfully decode it, you must specify the Claims that will be present in the JWT.

    + +

    One claim (by default, sub) will be used to represent the identity of the bearer. You can choose a different claim by supplying the subject option when creating an instance of CredentialsJWT, and you can further customize the resulting UserProfile by defining a UserProfileDelegate.

    +

     Usage Example

    + +

    To use CredentialsJWT using the default options:

    +
    import Credentials
    +import CredentialsJWT
    +import SwiftJWT
    +
    +// Defines the claims that must be present in a JWT.
    +struct MyClaims: Claims {
    +    let sub: String
    +}
    +
    +// Defines the method used to verify the signature of a JWT.
    +let jwtVerifier = .hs256(key: "<PrivateKey>".data(using: .utf8)!)
    +
    +// Create a CredentialsJWT plugin with default options.
    +let jwtCredentials = CredentialsJWT<MyClaims>(verifier: jwtVerifier)
    +
    +let authenticationMiddleware = Credentials()
    +authenticationMiddleware.register(plugin: jwtCredentials)
    +router.get("/myProtectedRoute", middleware: authenticationMiddleware)
    +
    + +

    Following successful authentication, the UserProfile will be minimally populated with the two required fields - id and displayName - both with the value of the JWT’s sub claim. The provider will be set to JWT.

    +

    Usage Example - custom claims

    + +

    To customize the name of the identity claim, and further populate the UserProfile fields, specify the subject and userProfileDelegate options as follows:

    +
    import Credentials
    +import CredentialsJWT
    +import SwiftJWT
    +
    +// Defines the claims that must be present in a JWT.
    +struct MyClaims: Claims {
    +    let id: Int
    +    let fullName: String
    +    let email: String
    +}
    +
    +struct MyDelegate: UserProfileDelegate {
    +    func update(userProfile: UserProfile, from dictionary: [String:Any]) {
    +        // `userProfile.id` already contains `id`
    +        userProfile.displayName = dictionary["fullName"]! as! String
    +        let email = UserProfile.UserProfileEmail(value: dictionary["email"]! as! String, type: "home")
    +        userProfile.emails = [email]
    +    }
    +}
    +
    +// Defines the method used to verify the signature of a JWT.
    +let jwtVerifier = .hs256(key: "<PrivateKey>".data(using: .utf8)!)
    +
    +// Create a CredentialsJWT plugin with default options.
    +let jwtCredentials = CredentialsJWT<MyClaims>(verifier: jwtVerifier, options: [CredentialsJWTOptions.subject: "id", CredentialsJWTOptions.userProfileDelegate: MyDelegate])
    +
    +let authenticationMiddleware = Credentials()
    +authenticationMiddleware.register(plugin: jwtCredentials)
    +router.get("/myProtectedRoute", middleware: authenticationMiddleware)
    +
    + +

    Following successful authentication, the UserProfile will be populated as follows:

    + +
      +
    • id: the id claim (converted to a String),
    • +
    • displayName: the fullName claim,
    • +
    • emails: an array with a single element, representing the email claim.
    • +

    Example of JWT authentication for Codable routes

    A Kitura Codable route can be authenticated using a JWT by using the JWT<C: Claims> type (defined by Swift-JWT) as a Type-Safe Middleware:

    @@ -148,7 +230,7 @@

    License

    diff --git a/docs/docsets/CredentialsJWT.docset/Contents/Resources/Documents/search.json b/docs/docsets/CredentialsJWT.docset/Contents/Resources/Documents/search.json index 14cc100..26d466c 100644 --- a/docs/docsets/CredentialsJWT.docset/Contents/Resources/Documents/search.json +++ b/docs/docsets/CredentialsJWT.docset/Contents/Resources/Documents/search.json @@ -1 +1 @@ -{"Structs/TypeSafeJWT.html#/s:14CredentialsJWT08TypeSafeB0V8verifier05SwiftB011JWTVerifierVSgvpZ":{"name":"verifier","abstract":"

    The verifier to use when verifying tokens. This must be configured before tokens can be successfully authenticated,","parent_name":"TypeSafeJWT"},"Structs/TypeSafeJWT.html#/s:14CredentialsJWT08TypeSafeB0V9cacheSizeSivpZ":{"name":"cacheSize","abstract":"

    The maximum size of the token cache. Defaults to 0, which is unlimited.

    ","parent_name":"TypeSafeJWT"},"Structs/TypeSafeJWT.html#/s:14CredentialsJWT08TypeSafeB0V15tokenTimeToLiveSdSgvpZ":{"name":"tokenTimeToLive","abstract":"

    The length of time this token should be deemed valid before it must be verified again. Defaults to nil, which is unlimited.

    ","parent_name":"TypeSafeJWT"},"Structs/CredentialsJWTOptions.html#/s:14CredentialsJWT0A10JWTOptionsV7subjectSSvpZ":{"name":"subject","abstract":"

    Determines the JWT claim that will be used for the identity of the user, (default is ‘sub’).

    ","parent_name":"CredentialsJWTOptions"},"Structs/CredentialsJWTOptions.html#/s:14CredentialsJWT0A10JWTOptionsV19userProfileDelegateSSvpZ":{"name":"userProfileDelegate","abstract":"

    An implementation of Credentials.UserProfileDelegate to update user profile.

    ","parent_name":"CredentialsJWTOptions"},"Structs/CredentialsJWTOptions.html":{"name":"CredentialsJWTOptions","abstract":"

    A list of options for authentication with JWT.

    "},"Structs/TypeSafeJWT.html":{"name":"TypeSafeJWT","abstract":"

    Represents the configuration for TypeSafeJWT authenication: the verification method, and the cache parameters."},"Extensions/JWT.html#/s:8SwiftJWT0B0V011CredentialsB0E2idSSvp":{"name":"id","abstract":"

    Note: This field does not apply to Type-safe JWT credentials. Use the JWT claims instead.

    ","parent_name":"JWT"},"Extensions/JWT.html#/s:8SwiftJWT0B0V011CredentialsB0E8providerSSvp":{"name":"provider","abstract":"

    Answers JWT.

    ","parent_name":"JWT"},"Extensions/JWT.html#/s:11Credentials08TypeSafeA0P12authenticate7request8response9onSuccess0G7Failure0G4Skipy6Kitura13RouterRequestC_AJ0L8ResponseCyxcy0K3Net14HTTPStatusCodeOSg_SDyS2SGSgtcyAR_ATtctFZ":{"name":"authenticate(request:response:onSuccess:onFailure:onSkip:)","parent_name":"JWT"},"Extensions/JWT.html":{"name":"JWT"},"Classes/CredentialsJWT.html#/s:11Credentials0A14PluginProtocolP10usersCacheSo7NSCacheCySo8NSStringCAA04BaseE7ElementCGSgvp":{"name":"usersCache","parent_name":"CredentialsJWT"},"Classes/CredentialsJWT.html#/s:11Credentials0A14PluginProtocolP4nameSSvp":{"name":"name","parent_name":"CredentialsJWT"},"Classes/CredentialsJWT.html#/s:11Credentials0A14PluginProtocolP11redirectingSbvp":{"name":"redirecting","parent_name":"CredentialsJWT"},"Classes/CredentialsJWT.html#/s:14CredentialsJWTAAC15tokenTimeToLiveSdSgvp":{"name":"tokenTimeToLive","abstract":"

    The time in seconds since the user profile was generated that the access token will be considered valid.

    ","parent_name":"CredentialsJWT"},"Classes/CredentialsJWT.html#/s:11Credentials0A14PluginProtocolP19userProfileDelegateAA04UsereF0_pSgvp":{"name":"userProfileDelegate","parent_name":"CredentialsJWT"},"Classes/CredentialsJWT.html#/s:14CredentialsJWTAAC8verifier7options15tokenTimeToLiveAByxG05SwiftB011JWTVerifierV_SDySSypGSgSdSgtcfc":{"name":"init(verifier:options:tokenTimeToLive:)","abstract":"

    Initialize a CredentialsGoogleToken instance.

    ","parent_name":"CredentialsJWT"},"Classes/CredentialsJWT.html#/s:11Credentials0A14PluginProtocolP12authenticate7request8response7options9onSuccess0H7Failure0H4Pass10inProgressy6Kitura13RouterRequestC_AL0O8ResponseCSDySSypGyAA11UserProfileCcy0N3Net14HTTPStatusCodeOSg_SDyS2SGSgtcyAW_AYtcyyctF":{"name":"authenticate(request:response:options:onSuccess:onFailure:onPass:inProgress:)","parent_name":"CredentialsJWT"},"Classes/CredentialsJWT.html":{"name":"CredentialsJWT","abstract":"

    Undocumented

    "},"Classes.html":{"name":"Classes","abstract":"

    The following classes are available globally.

    "},"Extensions.html":{"name":"Extensions","abstract":"

    The following extensions are available globally.

    "},"Structs.html":{"name":"Structures","abstract":"

    The following structures are available globally.

    "}} \ No newline at end of file +{"Structs/TypeSafeJWT.html#/s:14CredentialsJWT08TypeSafeB0V8verifier05SwiftB011JWTVerifierVSgvpZ":{"name":"verifier","abstract":"

    The verifier to use when verifying tokens. This must be configured before tokens can be successfully authenticated,","parent_name":"TypeSafeJWT"},"Structs/TypeSafeJWT.html#/s:14CredentialsJWT08TypeSafeB0V9cacheSizeSivpZ":{"name":"cacheSize","abstract":"

    The maximum size of the token cache. Defaults to 0, which is unlimited.

    ","parent_name":"TypeSafeJWT"},"Structs/TypeSafeJWT.html#/s:14CredentialsJWT08TypeSafeB0V15tokenTimeToLiveSdSgvpZ":{"name":"tokenTimeToLive","abstract":"

    The length of time this token should be deemed valid before it must be verified again. Defaults to nil, which is unlimited.

    ","parent_name":"TypeSafeJWT"},"Structs/CredentialsJWTOptions.html#/s:14CredentialsJWT0A10JWTOptionsV7subjectSSvpZ":{"name":"subject","abstract":"

    Determines the JWT claim that will be used for the identity of the user, (default is ‘sub’).

    ","parent_name":"CredentialsJWTOptions"},"Structs/CredentialsJWTOptions.html#/s:14CredentialsJWT0A10JWTOptionsV19userProfileDelegateSSvpZ":{"name":"userProfileDelegate","abstract":"

    An implementation of Credentials.UserProfileDelegate to update user profile.

    ","parent_name":"CredentialsJWTOptions"},"Structs/CredentialsJWTOptions.html":{"name":"CredentialsJWTOptions","abstract":"

    A list of options for authentication with JWT.

    "},"Structs/TypeSafeJWT.html":{"name":"TypeSafeJWT","abstract":"

    Represents the configuration for TypeSafeJWT authenication: the verification method, and the cache parameters."},"Extensions/JWT.html#/s:8SwiftJWT0B0V011CredentialsB0E2idSSvp":{"name":"id","abstract":"

    Note: This field does not apply to Type-safe JWT credentials. Use the JWT claims instead.

    ","parent_name":"JWT"},"Extensions/JWT.html#/s:8SwiftJWT0B0V011CredentialsB0E8providerSSvp":{"name":"provider","abstract":"

    Answers JWT.

    ","parent_name":"JWT"},"Extensions/JWT.html#/s:11Credentials08TypeSafeA0P12authenticate7request8response9onSuccess0G7Failure0G4Skipy6Kitura13RouterRequestC_AJ0L8ResponseCyxcy0K3Net14HTTPStatusCodeOSg_SDyS2SGSgtcyAR_ATtctFZ":{"name":"authenticate(request:response:onSuccess:onFailure:onSkip:)","parent_name":"JWT"},"Extensions/JWT.html":{"name":"JWT"},"Classes/CredentialsJWT.html#/s:14CredentialsJWTAAC4nameSSvp":{"name":"name","abstract":"

    The name of the plugin: JWT.

    ","parent_name":"CredentialsJWT"},"Classes/CredentialsJWT.html#/s:14CredentialsJWTAAC11redirectingSbvp":{"name":"redirecting","abstract":"

    An indication as to whether the plugin is redirecting or not. This plugin is not redirecting.

    ","parent_name":"CredentialsJWT"},"Classes/CredentialsJWT.html#/s:14CredentialsJWTAAC15tokenTimeToLiveSdSgvp":{"name":"tokenTimeToLive","abstract":"

    The time in seconds since the user profile was generated that the access token will be considered valid","parent_name":"CredentialsJWT"},"Classes/CredentialsJWT.html#/s:14CredentialsJWTAAC19userProfileDelegate0A004UserdE0_pSgvp":{"name":"userProfileDelegate","abstract":"

    A delegate for UserProfile manipulation. Use this to further populate the profile using","parent_name":"CredentialsJWT"},"Classes/CredentialsJWT.html#/s:14CredentialsJWTAAC8verifier7options15tokenTimeToLiveAByxG05SwiftB011JWTVerifierV_SDySSypGSgSdSgtcfc":{"name":"init(verifier:options:tokenTimeToLive:)","abstract":"

    Initialize a CredentialsJWT instance. Upon first receipt, a JWT will be verified to ensure the signature is valid,","parent_name":"CredentialsJWT"},"Classes/CredentialsJWT.html#/s:14CredentialsJWTAAC10usersCacheSo7NSCacheCySo8NSStringC0A004BaseD7ElementCGSgvp":{"name":"usersCache","abstract":"

    User profile cache.

    ","parent_name":"CredentialsJWT"},"Classes/CredentialsJWT.html#/s:14CredentialsJWTAAC12authenticate7request8response7options9onSuccess0G7Failure0G4Pass10inProgressy6Kitura13RouterRequestC_AK0N8ResponseCSDySSypGy0A011UserProfileCcy0M3Net14HTTPStatusCodeOSg_SDyS2SGSgtcyAW_AYtcyyctF":{"name":"authenticate(request:response:options:onSuccess:onFailure:onPass:inProgress:)","abstract":"

    Authenticate incoming request using a JWT.

    ","parent_name":"CredentialsJWT"},"Classes/CredentialsJWT.html":{"name":"CredentialsJWT","abstract":"

    A plugin for Kitura-Credentials supporting authentication using JSON Web Tokens.

    "},"Classes.html":{"name":"Classes","abstract":"

    The following classes are available globally.

    "},"Extensions.html":{"name":"Extensions","abstract":"

    The following extensions are available globally.

    "},"Structs.html":{"name":"Structures","abstract":"

    The following structures are available globally.

    "}} \ No newline at end of file diff --git a/docs/docsets/CredentialsJWT.docset/Contents/Resources/docSet.dsidx b/docs/docsets/CredentialsJWT.docset/Contents/Resources/docSet.dsidx index 187d3040ba91476d51cc8f535fe8720aeda22bae..aafc30748c954623f94f39b864972945d3c5a65d 100644 GIT binary patch delta 630 zcmZojXh_(=CZM;KfxnAilW!+q0Pk7ePTojfZk~%W7 z&cJq)ZR^IuMz+aiVv9Kah1eMy)g_zDCo75-)vN0&iHfBzKFJ%Na*g;xF8mQdB#3`{j)y3R3Cp9-Uuf*9sIK8Z((M(`+g~T?F zDtx&QU`-PxMMc1xKz5|K8pIcXl&A4c-YJ>J5yQ*Ipe)-cJXu}J7^GUp z(6A^qC9^0sxg;|$JvgbXz?X-OK~%PpIWIAH@>xl1b`u~YH8^;4rF1Wg-ZlnyMs_9M zF1B0THEi2>qqrBbhx2Rk@^Bh)>+)>kI?or#mCm<|^EK}|j+Ok~8w;D*CYP%%;s{^| z2N)xDLrlYnjhzh~Uhg2DnG6gsMO@(}*l5lcE!iZ@IJr(@1BXC08z|5ikwZ-iGt~Ig t*|cRF4E|m5q8?`EC4shz}f%+ delta 914 zcmZojXh_(=CZJcwz~9BM$+wd)fcGqKCvPM#H_t}yh1}I#&$zm{T#5^i?cmq zJIFSRt!!hV6WipiVv9JVh1eMy)g@c_Cnty(%NaTsrKY6jm1HL76dO1ingryOrf22_ z6y=xXC+Fu(mX=YN%pxJo?P2bgn3+>rlxpBHSxG`$%g4aqA}F=EAV04-)j8OuGB~)h zz`fGZ(acvuSpr(5HQHl5a`X! zqSWM)%)IpAq_To2UN#0%*+$vC#N5=$52Z8=2^e4kQWzXuR?sNK!^WT}+r&6|ql6Jb z_kWd85e2#5DX}=!)!a2FH5VAx&hEkKn=7SzS@g;o*bcEh=Ivse&0WJ*&Kt$Oh+TqT zi@uQ{~N3Z%1X%Qnh0PR^4`;NZ_<14SbvS@Fmh%?64_ UMv~)^w^5i46pa+eqjozB0RF!yO8@`> diff --git a/docs/docsets/CredentialsJWT.tgz b/docs/docsets/CredentialsJWT.tgz index b5081be3071643a030abd4c89924e7f8faaf6ddd..bb957ac2aef5404264a156b66b31f1956f0babac 100644 GIT binary patch literal 77181 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 diff --git a/docs/index.html b/docs/index.html index f6f5606..405cc3b 100644 --- a/docs/index.html +++ b/docs/index.html @@ -22,7 +22,7 @@ CredentialsJWT Docs - (94% documented) + (100% documented)

    @@ -105,13 +105,95 @@

    Kitura-CredentialsJWT

    -

    Plugin for the Credentials framework that supports authentication using JWTs.

    +

    A package enabling Kitura to authenticate users using JSON Web Tokens.

    Summary

    -

    Plugin for Kitura-Credentials framework that supports authentication using JSON Web Tokens.

    +

    This package provides two facilities:

    + +
      +
    • CredentialsJWT: A plugin for the Kitura-Credentials framework that supports JWT (token-based) authentication,
    • +
    • A TypeSafeMiddleware extension for the JWT type, enabling it to be used as authentication for Codable routes.
    • +

    Swift version

    The latest version of Kitura-CredentialsJWT requires Swift 4.0 or newer. You can download this version of the Swift binaries by following this link. Compatibility with other Swift versions is not guaranteed.

    +

    Using the CredentialsJWT plugin

    + +

    This plugin requires that the following HTTP headers are present on a request:

    + +
      +
    • X-token-type: must be JWT
    • +
    • Authorization: the JWT string, optionally prefixed with Bearer.
    • +
    + +

    The Swift-JWT library is used to decode the token supplied in the Authorization header. To successfully decode it, you must specify the Claims that will be present in the JWT.

    + +

    One claim (by default, sub) will be used to represent the identity of the bearer. You can choose a different claim by supplying the subject option when creating an instance of CredentialsJWT, and you can further customize the resulting UserProfile by defining a UserProfileDelegate.

    +

     Usage Example

    + +

    To use CredentialsJWT using the default options:

    +
    import Credentials
    +import CredentialsJWT
    +import SwiftJWT
    +
    +// Defines the claims that must be present in a JWT.
    +struct MyClaims: Claims {
    +    let sub: String
    +}
    +
    +// Defines the method used to verify the signature of a JWT.
    +let jwtVerifier = .hs256(key: "<PrivateKey>".data(using: .utf8)!)
    +
    +// Create a CredentialsJWT plugin with default options.
    +let jwtCredentials = CredentialsJWT<MyClaims>(verifier: jwtVerifier)
    +
    +let authenticationMiddleware = Credentials()
    +authenticationMiddleware.register(plugin: jwtCredentials)
    +router.get("/myProtectedRoute", middleware: authenticationMiddleware)
    +
    + +

    Following successful authentication, the UserProfile will be minimally populated with the two required fields - id and displayName - both with the value of the JWT’s sub claim. The provider will be set to JWT.

    +

    Usage Example - custom claims

    + +

    To customize the name of the identity claim, and further populate the UserProfile fields, specify the subject and userProfileDelegate options as follows:

    +
    import Credentials
    +import CredentialsJWT
    +import SwiftJWT
    +
    +// Defines the claims that must be present in a JWT.
    +struct MyClaims: Claims {
    +    let id: Int
    +    let fullName: String
    +    let email: String
    +}
    +
    +struct MyDelegate: UserProfileDelegate {
    +    func update(userProfile: UserProfile, from dictionary: [String:Any]) {
    +        // `userProfile.id` already contains `id`
    +        userProfile.displayName = dictionary["fullName"]! as! String
    +        let email = UserProfile.UserProfileEmail(value: dictionary["email"]! as! String, type: "home")
    +        userProfile.emails = [email]
    +    }
    +}
    +
    +// Defines the method used to verify the signature of a JWT.
    +let jwtVerifier = .hs256(key: "<PrivateKey>".data(using: .utf8)!)
    +
    +// Create a CredentialsJWT plugin with default options.
    +let jwtCredentials = CredentialsJWT<MyClaims>(verifier: jwtVerifier, options: [CredentialsJWTOptions.subject: "id", CredentialsJWTOptions.userProfileDelegate: MyDelegate])
    +
    +let authenticationMiddleware = Credentials()
    +authenticationMiddleware.register(plugin: jwtCredentials)
    +router.get("/myProtectedRoute", middleware: authenticationMiddleware)
    +
    + +

    Following successful authentication, the UserProfile will be populated as follows:

    + +
      +
    • id: the id claim (converted to a String),
    • +
    • displayName: the fullName claim,
    • +
    • emails: an array with a single element, representing the email claim.
    • +

    Example of JWT authentication for Codable routes

    A Kitura Codable route can be authenticated using a JWT by using the JWT<C: Claims> type (defined by Swift-JWT) as a Type-Safe Middleware:

    @@ -148,7 +230,7 @@

    License

    diff --git a/docs/search.json b/docs/search.json index 14cc100..26d466c 100644 --- a/docs/search.json +++ b/docs/search.json @@ -1 +1 @@ -{"Structs/TypeSafeJWT.html#/s:14CredentialsJWT08TypeSafeB0V8verifier05SwiftB011JWTVerifierVSgvpZ":{"name":"verifier","abstract":"

    The verifier to use when verifying tokens. This must be configured before tokens can be successfully authenticated,","parent_name":"TypeSafeJWT"},"Structs/TypeSafeJWT.html#/s:14CredentialsJWT08TypeSafeB0V9cacheSizeSivpZ":{"name":"cacheSize","abstract":"

    The maximum size of the token cache. Defaults to 0, which is unlimited.

    ","parent_name":"TypeSafeJWT"},"Structs/TypeSafeJWT.html#/s:14CredentialsJWT08TypeSafeB0V15tokenTimeToLiveSdSgvpZ":{"name":"tokenTimeToLive","abstract":"

    The length of time this token should be deemed valid before it must be verified again. Defaults to nil, which is unlimited.

    ","parent_name":"TypeSafeJWT"},"Structs/CredentialsJWTOptions.html#/s:14CredentialsJWT0A10JWTOptionsV7subjectSSvpZ":{"name":"subject","abstract":"

    Determines the JWT claim that will be used for the identity of the user, (default is ‘sub’).

    ","parent_name":"CredentialsJWTOptions"},"Structs/CredentialsJWTOptions.html#/s:14CredentialsJWT0A10JWTOptionsV19userProfileDelegateSSvpZ":{"name":"userProfileDelegate","abstract":"

    An implementation of Credentials.UserProfileDelegate to update user profile.

    ","parent_name":"CredentialsJWTOptions"},"Structs/CredentialsJWTOptions.html":{"name":"CredentialsJWTOptions","abstract":"

    A list of options for authentication with JWT.

    "},"Structs/TypeSafeJWT.html":{"name":"TypeSafeJWT","abstract":"

    Represents the configuration for TypeSafeJWT authenication: the verification method, and the cache parameters."},"Extensions/JWT.html#/s:8SwiftJWT0B0V011CredentialsB0E2idSSvp":{"name":"id","abstract":"

    Note: This field does not apply to Type-safe JWT credentials. Use the JWT claims instead.

    ","parent_name":"JWT"},"Extensions/JWT.html#/s:8SwiftJWT0B0V011CredentialsB0E8providerSSvp":{"name":"provider","abstract":"

    Answers JWT.

    ","parent_name":"JWT"},"Extensions/JWT.html#/s:11Credentials08TypeSafeA0P12authenticate7request8response9onSuccess0G7Failure0G4Skipy6Kitura13RouterRequestC_AJ0L8ResponseCyxcy0K3Net14HTTPStatusCodeOSg_SDyS2SGSgtcyAR_ATtctFZ":{"name":"authenticate(request:response:onSuccess:onFailure:onSkip:)","parent_name":"JWT"},"Extensions/JWT.html":{"name":"JWT"},"Classes/CredentialsJWT.html#/s:11Credentials0A14PluginProtocolP10usersCacheSo7NSCacheCySo8NSStringCAA04BaseE7ElementCGSgvp":{"name":"usersCache","parent_name":"CredentialsJWT"},"Classes/CredentialsJWT.html#/s:11Credentials0A14PluginProtocolP4nameSSvp":{"name":"name","parent_name":"CredentialsJWT"},"Classes/CredentialsJWT.html#/s:11Credentials0A14PluginProtocolP11redirectingSbvp":{"name":"redirecting","parent_name":"CredentialsJWT"},"Classes/CredentialsJWT.html#/s:14CredentialsJWTAAC15tokenTimeToLiveSdSgvp":{"name":"tokenTimeToLive","abstract":"

    The time in seconds since the user profile was generated that the access token will be considered valid.

    ","parent_name":"CredentialsJWT"},"Classes/CredentialsJWT.html#/s:11Credentials0A14PluginProtocolP19userProfileDelegateAA04UsereF0_pSgvp":{"name":"userProfileDelegate","parent_name":"CredentialsJWT"},"Classes/CredentialsJWT.html#/s:14CredentialsJWTAAC8verifier7options15tokenTimeToLiveAByxG05SwiftB011JWTVerifierV_SDySSypGSgSdSgtcfc":{"name":"init(verifier:options:tokenTimeToLive:)","abstract":"

    Initialize a CredentialsGoogleToken instance.

    ","parent_name":"CredentialsJWT"},"Classes/CredentialsJWT.html#/s:11Credentials0A14PluginProtocolP12authenticate7request8response7options9onSuccess0H7Failure0H4Pass10inProgressy6Kitura13RouterRequestC_AL0O8ResponseCSDySSypGyAA11UserProfileCcy0N3Net14HTTPStatusCodeOSg_SDyS2SGSgtcyAW_AYtcyyctF":{"name":"authenticate(request:response:options:onSuccess:onFailure:onPass:inProgress:)","parent_name":"CredentialsJWT"},"Classes/CredentialsJWT.html":{"name":"CredentialsJWT","abstract":"

    Undocumented

    "},"Classes.html":{"name":"Classes","abstract":"

    The following classes are available globally.

    "},"Extensions.html":{"name":"Extensions","abstract":"

    The following extensions are available globally.

    "},"Structs.html":{"name":"Structures","abstract":"

    The following structures are available globally.

    "}} \ No newline at end of file +{"Structs/TypeSafeJWT.html#/s:14CredentialsJWT08TypeSafeB0V8verifier05SwiftB011JWTVerifierVSgvpZ":{"name":"verifier","abstract":"

    The verifier to use when verifying tokens. This must be configured before tokens can be successfully authenticated,","parent_name":"TypeSafeJWT"},"Structs/TypeSafeJWT.html#/s:14CredentialsJWT08TypeSafeB0V9cacheSizeSivpZ":{"name":"cacheSize","abstract":"

    The maximum size of the token cache. Defaults to 0, which is unlimited.

    ","parent_name":"TypeSafeJWT"},"Structs/TypeSafeJWT.html#/s:14CredentialsJWT08TypeSafeB0V15tokenTimeToLiveSdSgvpZ":{"name":"tokenTimeToLive","abstract":"

    The length of time this token should be deemed valid before it must be verified again. Defaults to nil, which is unlimited.

    ","parent_name":"TypeSafeJWT"},"Structs/CredentialsJWTOptions.html#/s:14CredentialsJWT0A10JWTOptionsV7subjectSSvpZ":{"name":"subject","abstract":"

    Determines the JWT claim that will be used for the identity of the user, (default is ‘sub’).

    ","parent_name":"CredentialsJWTOptions"},"Structs/CredentialsJWTOptions.html#/s:14CredentialsJWT0A10JWTOptionsV19userProfileDelegateSSvpZ":{"name":"userProfileDelegate","abstract":"

    An implementation of Credentials.UserProfileDelegate to update user profile.

    ","parent_name":"CredentialsJWTOptions"},"Structs/CredentialsJWTOptions.html":{"name":"CredentialsJWTOptions","abstract":"

    A list of options for authentication with JWT.

    "},"Structs/TypeSafeJWT.html":{"name":"TypeSafeJWT","abstract":"

    Represents the configuration for TypeSafeJWT authenication: the verification method, and the cache parameters."},"Extensions/JWT.html#/s:8SwiftJWT0B0V011CredentialsB0E2idSSvp":{"name":"id","abstract":"

    Note: This field does not apply to Type-safe JWT credentials. Use the JWT claims instead.

    ","parent_name":"JWT"},"Extensions/JWT.html#/s:8SwiftJWT0B0V011CredentialsB0E8providerSSvp":{"name":"provider","abstract":"

    Answers JWT.

    ","parent_name":"JWT"},"Extensions/JWT.html#/s:11Credentials08TypeSafeA0P12authenticate7request8response9onSuccess0G7Failure0G4Skipy6Kitura13RouterRequestC_AJ0L8ResponseCyxcy0K3Net14HTTPStatusCodeOSg_SDyS2SGSgtcyAR_ATtctFZ":{"name":"authenticate(request:response:onSuccess:onFailure:onSkip:)","parent_name":"JWT"},"Extensions/JWT.html":{"name":"JWT"},"Classes/CredentialsJWT.html#/s:14CredentialsJWTAAC4nameSSvp":{"name":"name","abstract":"

    The name of the plugin: JWT.

    ","parent_name":"CredentialsJWT"},"Classes/CredentialsJWT.html#/s:14CredentialsJWTAAC11redirectingSbvp":{"name":"redirecting","abstract":"

    An indication as to whether the plugin is redirecting or not. This plugin is not redirecting.

    ","parent_name":"CredentialsJWT"},"Classes/CredentialsJWT.html#/s:14CredentialsJWTAAC15tokenTimeToLiveSdSgvp":{"name":"tokenTimeToLive","abstract":"

    The time in seconds since the user profile was generated that the access token will be considered valid","parent_name":"CredentialsJWT"},"Classes/CredentialsJWT.html#/s:14CredentialsJWTAAC19userProfileDelegate0A004UserdE0_pSgvp":{"name":"userProfileDelegate","abstract":"

    A delegate for UserProfile manipulation. Use this to further populate the profile using","parent_name":"CredentialsJWT"},"Classes/CredentialsJWT.html#/s:14CredentialsJWTAAC8verifier7options15tokenTimeToLiveAByxG05SwiftB011JWTVerifierV_SDySSypGSgSdSgtcfc":{"name":"init(verifier:options:tokenTimeToLive:)","abstract":"

    Initialize a CredentialsJWT instance. Upon first receipt, a JWT will be verified to ensure the signature is valid,","parent_name":"CredentialsJWT"},"Classes/CredentialsJWT.html#/s:14CredentialsJWTAAC10usersCacheSo7NSCacheCySo8NSStringC0A004BaseD7ElementCGSgvp":{"name":"usersCache","abstract":"

    User profile cache.

    ","parent_name":"CredentialsJWT"},"Classes/CredentialsJWT.html#/s:14CredentialsJWTAAC12authenticate7request8response7options9onSuccess0G7Failure0G4Pass10inProgressy6Kitura13RouterRequestC_AK0N8ResponseCSDySSypGy0A011UserProfileCcy0M3Net14HTTPStatusCodeOSg_SDyS2SGSgtcyAW_AYtcyyctF":{"name":"authenticate(request:response:options:onSuccess:onFailure:onPass:inProgress:)","abstract":"

    Authenticate incoming request using a JWT.

    ","parent_name":"CredentialsJWT"},"Classes/CredentialsJWT.html":{"name":"CredentialsJWT","abstract":"

    A plugin for Kitura-Credentials supporting authentication using JSON Web Tokens.

    "},"Classes.html":{"name":"Classes","abstract":"

    The following classes are available globally.

    "},"Extensions.html":{"name":"Extensions","abstract":"

    The following extensions are available globally.

    "},"Structs.html":{"name":"Structures","abstract":"

    The following structures are available globally.

    "}} \ No newline at end of file diff --git a/docs/undocumented.json b/docs/undocumented.json index 03fc3e1..1c9826c 100644 --- a/docs/undocumented.json +++ b/docs/undocumented.json @@ -1,12 +1,6 @@ { "warnings": [ - { - "file": "/Users/travis/build/IBM-Swift/Kitura-CredentialsJWT/Sources/CredentialsJWT/CredentialsJWT.swift", - "line": 23, - "symbol": "CredentialsJWT", - "symbol_kind": "source.lang.swift.decl.class", - "warning": "undocumented" - } + ], "source_directory": "/Users/travis/build/IBM-Swift/Kitura-CredentialsJWT" } \ No newline at end of file