[Pitch] JWT/JWS/JWT support kit

Hello,

Introduction

I would like to pitch JWSETKit to the SSWG.
JWSETKit is a library that supports create, sign, decode and verify JWS and JWT objects and encrypt/decrypt using JWE standard.

Motivation

JSON Web Token (JWT) is a compact claims representation format intended for space constrained environments such as HTTP Authorization headers and URI query parameters.

Usage

To create a JWT instance from String or Data,

let jwt = try JSONWebToken(from: authorization)

To assign a JWT to URLRequest's

Authorization header using Foundation/URLRequest/authorizationToken ,

var request = URLRequest(url: URL(string: "https://www.example.com")!)
request.authorizationToken = jwt

To convert back a JWT instance to string representation,

let jwtString = try String(jws: jwt)

or

let jwtString = jwt.description

Accessing Claims

Various claims, including registered and claims defined by OpenID Connect Core

are predefined for JSON Web Token's payload.

Claim names are more descriptive than keys defined by IANA Registry,

for example sub claim became JSONWebTokenClaimsRegisteredParameters/subject

and iat became JSONWebTokenClaimsRegisteredParameters/issuedAt.

For a complete list of predefined claims check JSONWebTokenClaimsRegisteredParameters,

JSONWebTokenClaimsOAuthParameters, JSONWebTokenClaimsPublicOIDCAuthParameters and

JSONWebTokenClaimsPublicOIDCStandardParameters.

For StringORURL types that are common to be a URL, there are two accessors

for String and URL, e.g.

let subjectString = jwt.subject // `sub` claim as String
let subjectURL = jwt.subjectURL // `sub` claim parsed as URL

Date types are converted automatically from Unix Epoch to Swift's Date.

For types that can be either a string or an array of strings, data type is [String],

let singleAudience = jwt.audience.first

Also JSONWebTokenClaimsOAuthParameters/scope items are separated by

space according to standard and a list of items can be accessed

using JSONWebTokenClaimsOAuthParameters/scopes.

Verify Signature

To verify the signature(s), first create public key(s)] then use

verifySignature(using:) to verify signature(s).

If an array of keys is passed to verifySignature(using:) the most appropriate

key will be selected according alg value and then kid value if multiple keys

are candidates regarding JOSEHeader counterpart of signature.

Using symmetric key for HS256, etc.,

let hmacKey = SymmetricKey(data: hmacKeyData)
do {
    try jwt.verifySignature(using: hmacKey)
} catch {
    print("signature is invalid.")
}
8 Likes

+1 on this, JWT libraries are valuable and needed.

One point - currently there are some failing tests and the tests crash on Linux, I recommend setting up Linux CI for a server project

2 Likes

Thanks @0xTim,

I've checked and resolved Linux issues and pushed a new commit:

  • I've added Linux build in github actions' file
  • RSA-PKCS-1.5 is not supported on linux thus I deactivated all related tests in linux. I think it's negligible as implementation requirement is Recommended-.
  • Converting KeyPath to string using String.init(describing:) is not supported on non-Apple platforms. I've added dynamic member lookup using String.
  • Localization using Bundle.localizing method causes crash probably due to a bug in swift-corelibs-foundation. I've disabled the localization until it got fixed.

Hi @amosavian !

I've been assigned from the sswg to handle the process for this proposal, but noticed we didn't get to making a formal proposal PR.

Would you mind making the pitch into a proposal PR and send it over to Pull requests ยท swift-server/sswg ยท GitHub then we'd kick off the review process.

Feel free to ping me so I don't miss it, thank you in advance!

Thanks Konrad, I will do it soon.

2 Likes

Sweet, thank you! Looking forward to it!

Hi @ktoso,

Please check the PR at Propose JWSETKit to the SSWG Incubation Process by amosavian ยท Pull Request #101 ยท swift-server/sswg ยท GitHub

Thanks

1 Like

Thank you, very nice!

Kicked off the review here: SSWG-0029: JWSETKit

Please keep an eye on it to answer any review questions that might arrive.

1 Like