profile
viewpoint

vapor/jwt 266

Vapor JWT provider

vapor-community/PassKit 17

Vapor implementation for Apple's PassKit server requirements.

grosch/fluent 0

🖋 Swift ORM framework (queries, models, and relations) for building NoSQL and SQL database integrations.

grosch/sql 0

*️⃣ Build SQL queries in Swift. Extensible, protocol-based design that supports DQL, DML, and DDL.

grosch/vapor 0

💧 A server-side Swift web framework.

issue openedvapor/jwt-kit

EdDSA Support

Please consider supporting Ed25519 signature.

created time in 14 days

issue commentvapor/jwt

Allow configuration of URIs in JWT helpers

I have created a pull request to solve this issue. It uses a separate Lock to reset the EndpointCache when the URI is modified.

andtie

comment created time in a month

PR opened vapor/jwt

Allow configuration of URIs in JWT helpers

<!-- 🚀 Thank you for contributing! -->

<!-- Describe your changes clearly and use examples if possible. -->

<!-- When this PR is merged, the title and body will be --> <!-- used to generate a release automatically. --> This PR closes #134. It exposes the URIs for the JWKS endpoints in the JWT-helpers for Apple, Microsoft and Google.

+57 -6

0 comment

3 changed files

pr created time in a month

PR opened vapor/jwt-kit

Unify vendor issuer message, correct microsoft

<!-- 🚀 Thank you for contributing! --> Not sure if I'm correct on this, but the issue failure message from a Microsoft token said Token not provided by Apple. Additionally unified error message between 3 vendors

<!-- Describe your changes clearly and use examples if possible. -->

  • Unify messaging for issuer JWTError.claimVerificationFailure for Apple/Microsoft/Google: Token not provided by INSERT_VENDOR
  • change Microsoft message saying Token not provided by Apple to Token not provided by Microsoft

<!-- When this PR is merged, the title and body will be --> Unify Vendor Claim Verification Failure Message

<!-- used to generate a release automatically. -->

+2 -2

0 comment

2 changed files

pr created time in a month

issue commentvapor/jwt

Allow configuration of URIs in JWT helpers

If you set the app identifier to use Applications storage, you can wrap it in a lock, similar to how the HTTP Client works https://github.com/vapor/vapor/blob/master/Sources/Vapor/HTTP/Client/Application%2BHTTP%2BClient.swift#L19-L38

andtie

comment created time in 2 months

push eventvapor/jwt-kit

Tim Condon

commit sha b9c8950be2530c5f55407fca723c960eae88a95f

Delete FUNDING.yml (#48)

view details

push time in 2 months

delete branch vapor/jwt-kit

delete branch : 0xTim-patch-1

delete time in 2 months

PR merged vapor/jwt-kit

Reviewers
Delete FUNDING.yml

Migrate funding to the file in the central org repo

+0 -1

0 comment

1 changed file

0xTim

pr closed time in 2 months

push eventvapor/jwt

Tim Condon

commit sha 7a416550b424350e4788ff5880ccc90803ddca90

Delete FUNDING.yml (#135)

view details

push time in 2 months

delete branch vapor/jwt

delete branch : 0xTim-patch-1

delete time in 2 months

PR merged vapor/jwt

Reviewers
Delete FUNDING.yml

Migrate funding to the file in the central org repo

+0 -2

0 comment

1 changed file

0xTim

pr closed time in 2 months

PR opened vapor/jwt-kit

Reviewers
Delete FUNDING.yml

Migrate funding to the file in the central org repo

+0 -1

0 comment

1 changed file

pr created time in 2 months

create barnchvapor/jwt-kit

branch : 0xTim-patch-1

created branch time in 2 months

PR opened vapor/jwt

Delete FUNDING.yml

Migrate funding to the file in the central org repo

+0 -2

0 comment

1 changed file

pr created time in 2 months

create barnchvapor/jwt

branch : 0xTim-patch-1

created branch time in 2 months

issue openedvapor/jwt-kit

Support Cocoapods

Hello there 👋 I would like to use this library with Cocoapods.

if you want I can help.

created time in 2 months

issue commentvapor/jwt

Allow configuration of URIs in JWT helpers

On further reflection, I think the current implementation of setting the applicationIdentifier is also not thread-safe. I turned on Thread Sanitizer and wrote a small test to verify this:

    func testDataRace() throws {
        let app = Application(.testing)
        defer { app.shutdown() }
        let exp = expectation(description: "data race")

        (0...10).forEach { _ in
            DispatchQueue.global().async { app.jwt.microsoft.applicationIdentifier = "" }
        }

        DispatchQueue.global().async { exp.fulfill() }
        waitForExpectations(timeout: 1, handler: nil)
    }

This produces the expected runtime-exception: runtime: Threading Issues: Data race in (extension in JWT):Vapor.Application.JWT.Apple.applicationIdentifier.setter : Swift.Optional<Swift.String> at 0x7b1000039300

However, as mentioned above, in practice this probably isn't a problem, because setting the applicationIdentifier (and Endpoint-URI) more than once wouldn't make sense anyway. For the case of the jwksEndpoint however, it may be a little bit more dangerous because changing the URI would necessarily invalidate the EndpointCache.

This leaves us with the options to either (a) expose an jwksEndpoint similar to the applicationIdentifier and ignore potential threading problems, (b) wrap everything in locks or (c) do a bigger refactor of the whole thing (there is a lot of duplicated code anyway) with the current problems in mind.

I would be happy to help with the implementation if you have a preference.

andtie

comment created time in 2 months

issue commentvapor/jwt

Allow configuration of URIs in JWT helpers

Of course, the problem is more complicated than I first thought 😉. The JWT- and Microsoft-structs are recreated on every access and all data is stored in the respective Storage-class. However, the URI cannot be stored in the storage, because it is already needed in the initializer of the storage itself.

I see several possibilities to overcome this problem:

  1. Store the URI in a static variable on the Mircosoft-struct such that it can be set like this: Application.JWT.Microsoft.jwksEndpoint = "...". This is simple, but afaik setting of the static variable is not thread-safe. In practice this probably isn't a problem, because setting the URI makes only sense once during the configuration of the app anyway.
  2. We could add a second storage / configuration class, just to store the URI. This should be clean, but very verbose and adds a lot of duplicated code.
  3. We could add a new additional initializer with the URI as a parameter to the extension. E.g.:
extension Application.JWT {
     public func microsoft(jwksEndpoint: URI) -> Microsoft { ... }
     ...
}

This way, we do not have to store the URI. But we would also have to parametrize the microsoft-extension on Request.JWT such that it passes the parameter when accessing the signers:

extension Request.JWT {
     public func microsoft(jwksEndpoint: URI) -> Microsoft { ... }
     ...
}

For (1) and (2) there is the additional constraint that a user must configure the URI before the applicationIdentifier. Otherwise it would have no effect. Perhaps we could log a warning if this happens, similar to how it is done in HTTPServer.Configuration.

If we would go down the road of (3) and parametrize the extensions on Request.JWT, one could probably go further and unify the Apple, Google and Microsoft-extensions as well. E.g., by passing a complete configuration struct.

Of course there are also other possibilities, such as requiring an explicit initialization of the storage before the first request. But this would then probably break API compatibility.

I would love to hear your thoughts on this.

andtie

comment created time in 2 months

issue commentvapor/jwt

Allow configuration of URIs in JWT helpers

Thanks for your replay. I am happy to do the PR.

andtie

comment created time in 2 months

issue commentvapor/jwt

Allow configuration of URIs in JWT helpers

I think this could be a useful enhancement. If you're happy to do the PR feel free otherwise we can add it to the backlog

andtie

comment created time in 2 months

issue closedvapor/jwt-kit

Can't verify with JWKSigner using an EC key

I may be doing something wrong here. I copied the test code from the "Add ECDSAKey support to JWKS" commit.

There are 2 issues here. First, if I replace the x, y, and privateKey values with the values from another p384 ec key, it throws an error Unable to interpret x as BN when I try to create the signer. So, instead I create the signer with a PEM and it works.

The next issue is when I try to verify, it throws: unknown kid: JWKIdentifier(string: "vapor")

` func testVerifyingECDSAKeyUsingJWK() throws { struct Foo: JWTPayload { var bar: Int func verify(using signer: JWTSigner) throws { } }

    //Tried both of these
    //https://mkjwk.org
    //openssl ecparam -name secp384r1 -genkey -noout | docker run -i danedmunds/pem-to-jwk:latest
    
    // Replace x,y and d from the test with new values
    let x = "3an5PvBSbJHrpSJUfwTKGw45eOXIlyHWEnoxK7QU2Z2WIlpBnH2af_qLfp0sOK7d"
    let y = "08OPOmWn509MbNqjLxA-0TRI_TDuq9Htj-kxcTDszsdXyROFXdaaOpngHlD6vt7b"
    let privateKey = "hbSA78pRzIflWhTdl_plFvWRpqqD-c2NQji4U3pFqV6pWFCEZGT-O7eA0OIVVfLv"
    
    // Creating the signer this way throws Unable to interpret x as BN

// let privateSigner = JWTSigner.es384(key: try ECDSAKey(parameters: .init(x: x, y: y), curve: .p384, privateKey: privateKey)) // let jwt = try privateSigner.sign(Foo(bar: 42), kid: "vapor")

    let privatePEMKey = """
        -----BEGIN PRIVATE KEY-----
        ME4CAQAwEAYHKoZIzj0CAQYFK4EEACIENzA1AgEBBDDdqfk+8FJskeulIlR/BMob
        Djl45ciXIdYSejErtBTZnZYiWkGcfZp/+ot+nSw4rt0=
        -----END PRIVATE KEY-----
        """
    let privatePEMSigner = JWTSigner.es256(key: try! ECDSAKey.private(pem: privatePEMKey))
    let jwt = try privatePEMSigner.sign(Foo(bar: 42), kid: "vapor")
    
    
    // verify using jwks without alg
    let jwksString = """
         {
             "keys": [
                 {
                     "kty": "EC",
                     "use": "sig",
                     "kid": "vapor",
                     "x": "\(x)",
                     "y": "\(y)"
                  }
             ]
         }
         """
    
    let signers = JWTSigners()
    try signers.use(jwksJSON: jwksString)
    // If I create the signer with PEM, I get this far.
    // However, verify() throws: unknown kid: JWKIdentifier(string: "vapor")
    let foo = try signers.verify(jwt, as: Foo.self)
    XCTAssertEqual(foo.bar, 42)
}`

closed time in 3 months

saltzmanjoelh

issue openedvapor/jwt-kit

Error when trying to create or verify with EC keys

I may be doing something wrong here. I copied the test code from the "Add ECDSAKey support to JWKS" commit.

There are 2 issues here. First, if I replace the x, y, and privateKey values with the values from another p384 ec key, it throws an error Unable to interpret x as BN when I try to create the signer. So, instead I create the signer with a PEM and it works.

The next issue is when I try to verify, it throws: unknown kid: JWKIdentifier(string: "vapor")

` func testVerifyingECDSAKeyUsingJWK() throws { struct Foo: JWTPayload { var bar: Int func verify(using signer: JWTSigner) throws { } }

    //Tried both of these
    //https://mkjwk.org
    //openssl ecparam -name secp384r1 -genkey -noout | docker run -i danedmunds/pem-to-jwk:latest
    
    // Replace x,y and d from the test with new values
    let x = "3an5PvBSbJHrpSJUfwTKGw45eOXIlyHWEnoxK7QU2Z2WIlpBnH2af_qLfp0sOK7d"
    let y = "08OPOmWn509MbNqjLxA-0TRI_TDuq9Htj-kxcTDszsdXyROFXdaaOpngHlD6vt7b"
    let privateKey = "hbSA78pRzIflWhTdl_plFvWRpqqD-c2NQji4U3pFqV6pWFCEZGT-O7eA0OIVVfLv"
    
    // Creating the signer this way throws Unable to interpret x as BN

// let privateSigner = JWTSigner.es384(key: try ECDSAKey(parameters: .init(x: x, y: y), curve: .p384, privateKey: privateKey)) // let jwt = try privateSigner.sign(Foo(bar: 42), kid: "vapor")

    let privatePEMKey = """
        -----BEGIN PRIVATE KEY-----
        ME4CAQAwEAYHKoZIzj0CAQYFK4EEACIENzA1AgEBBDDdqfk+8FJskeulIlR/BMob
        Djl45ciXIdYSejErtBTZnZYiWkGcfZp/+ot+nSw4rt0=
        -----END PRIVATE KEY-----
        """
    let privatePEMSigner = JWTSigner.es256(key: try! ECDSAKey.private(pem: privatePEMKey))
    let jwt = try privatePEMSigner.sign(Foo(bar: 42), kid: "vapor")
    
    
    // verify using jwks without alg
    let jwksString = """
         {
             "keys": [
                 {
                     "kty": "EC",
                     "use": "sig",
                     "kid": "vapor",
                     "x": "\(x)",
                     "y": "\(y)"
                  }
             ]
         }
         """
    
    let signers = JWTSigners()
    try signers.use(jwksJSON: jwksString)
    // If I create the signer with PEM, I get this far.
    // However, verify() throws: unknown kid: JWKIdentifier(string: "vapor")
    let foo = try signers.verify(jwt, as: Foo.self)
    XCTAssertEqual(foo.bar, 42)
}`

created time in 3 months

issue openedvapor/jwt-kit

Can't verify with JWKSigner using an EC key

I may be doing something wrong here. I copied the test code from the "Add ECDSAKey support to JWKS" commit.

There are 2 issues here. First, if I replace the x, y, and privateKey values with the values from another p384 ec key, it throws an error Unable to interpret x as BN when I try to create the signer. So, instead I create the signer with a PEM and it works.

The next issue is when I try to verify, it throws: unknown kid: JWKIdentifier(string: "vapor")

` func testVerifyingECDSAKeyUsingJWK() throws { struct Foo: JWTPayload { var bar: Int func verify(using signer: JWTSigner) throws { } }

    //Tried both of these
    //https://mkjwk.org
    //openssl ecparam -name secp384r1 -genkey -noout | docker run -i danedmunds/pem-to-jwk:latest
    
    // Replace x,y and d from the test with new values
    let x = "3an5PvBSbJHrpSJUfwTKGw45eOXIlyHWEnoxK7QU2Z2WIlpBnH2af_qLfp0sOK7d"
    let y = "08OPOmWn509MbNqjLxA-0TRI_TDuq9Htj-kxcTDszsdXyROFXdaaOpngHlD6vt7b"
    let privateKey = "hbSA78pRzIflWhTdl_plFvWRpqqD-c2NQji4U3pFqV6pWFCEZGT-O7eA0OIVVfLv"
    
    // Creating the signer this way throws Unable to interpret x as BN

// let privateSigner = JWTSigner.es384(key: try ECDSAKey(parameters: .init(x: x, y: y), curve: .p384, privateKey: privateKey)) // let jwt = try privateSigner.sign(Foo(bar: 42), kid: "vapor")

    let privatePEMKey = """
        -----BEGIN PRIVATE KEY-----
        ME4CAQAwEAYHKoZIzj0CAQYFK4EEACIENzA1AgEBBDDdqfk+8FJskeulIlR/BMob
        Djl45ciXIdYSejErtBTZnZYiWkGcfZp/+ot+nSw4rt0=
        -----END PRIVATE KEY-----
        """
    let privatePEMSigner = JWTSigner.es256(key: try! ECDSAKey.private(pem: privatePEMKey))
    let jwt = try privatePEMSigner.sign(Foo(bar: 42), kid: "vapor")
    
    
    // verify using jwks without alg
    let jwksString = """
         {
             "keys": [
                 {
                     "kty": "EC",
                     "use": "sig",
                     "kid": "vapor",
                     "x": "\(x)",
                     "y": "\(y)"
                  }
             ]
         }
         """
    
    let signers = JWTSigners()
    try signers.use(jwksJSON: jwksString)
    // If I create the signer with PEM, I get this far.
    // However, verify() throws: unknown kid: JWKIdentifier(string: "vapor")
    let foo = try signers.verify(jwt, as: Foo.self)
    XCTAssertEqual(foo.bar, 42)
}`

created time in 3 months

issue openedvapor/jwt

Allow configuration of URIs in JWT helpers

I am facing the problem that I need to specify another URI to get the JWKS for the Microsoft issuer. It is currently hardcoded to "https://login.microsoftonline.com/common/discovery/keys", but I need the "v2.0"-version at "https://login.microsoftonline.com/common/discovery/v2.0/keys".

The only waythat I found to work around this issue is to copy and rename all of the JWT-Microsoft helpers (in JWT+Micorsoft.swift) and change the URI in the copy. I would prefer it, if I could only change the URI without having to need to copy the whole other logic.

Therefore, I propose to add another public property (e.g. named jwksEndpoint) similar to applicationIdentifier that can be changed via app.jwt.microsoft.jwksEndpoint.

The same could be done for the Apple and Google helpers.

created time in 3 months

issue commentvapor-community/PassKit

Build Error in Xcode 12

Sorry, I'm new to Vapor. It Looks like I needed to add it as a package to an existing project and not to run it by itself.

appfactoryCo

comment created time in 3 months

issue closedvapor-community/PassKit

Build Error in Xcode 12

Thanks for this great effort. There is this build error in Xcode 12:

'ASN1_ENCODING_st' has different definitions in different modules; first difference is definition in module 'CNIOBoringSSL' found field

closed time in 3 months

appfactoryCo

issue openedvapor-community/PassKit

Build Error in Xcode 12

Thanks for this great effort. There is this build error in Xcode 12:

'ASN1_ENCODING_st' has different definitions in different modules; first difference is definition in module 'CNIOBoringSSL' found field

created time in 3 months

more