Code Monkey home page Code Monkey logo

jwt's Introduction

jwt's People

Contributors

0xtim avatar bennydebock avatar cellane avatar chariot6 avatar grosch avatar gwynne avatar jaapwijnen avatar jiahan-wu avatar joannis avatar kevinup7 avatar loganwright avatar martinlasek avatar mrmage avatar pedantix avatar ptoffy avatar siemensikkema avatar tanner0101 avatar valeriomazzeo avatar vzsg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jwt's Issues

Missing license

Hi,
Do you have any plans for introducing specific license to this project?
I'd like to use a part of this library in my open source project if possible, though lack of license makes it a bit unclear if I can do so, especially that I don't really want to depend on the whole package, only on the ecliptic curve algorithm implementation.

Allow JWT to be extended by user

As per the discord discussions, logging this here.

There's lots of good and relevant code within JWT, but it's not possible to reuse some key pieces when working with another provider. For example, I'd think it would be nice if you could examine the Apple+JWT.swift or Google+JWT.swift and then roll your own verifier that extends Request.JWT and Application.JWT.

If you try to do this though, you'll get inaccessible due to internal protection for some pieces.

import Vapor
import JWT

extension Request.JWT {
    public var cognito: Cognito{
        .init(request: self.request)
    }

    public struct Cognito{
        let request: Request
     ...

I believe the same will happen with regards to the application property on the extension of Application.JWT.

Creating RS256 signer from base64-encoded key

I can't seem to get the library to create a JWT using the RS256 signer. I have some key that looks like this:
-----BEGIN PRIVATE KEY-----\nMIIEvA......a5efqA==\n-----END PRIVATE KEY-----\n
First, I removed the beginning and ending tags, and the \n's, so I have just the base64-key: MIIEvA...a5efqA==
as a string. I then used the .bytes method (that was used in the playground example) to convert it to the correct type, and initialized the signer like so:
let signer = try RS256(key: key.bytes)
However, this throws an error: "JWT error: Could not create key". Why is this? I tried using Data and Array to convert the string to [UInt8] as well, but that gave the same error. Is there a better way to create the signer object without doing the type conversion myself?
Thank you!

build failing on heroku

remote: Linking ./.build/release/App
remote: /tmp/build_9e6662da1ad3a4a4089c8520505ca138/.build/release/App.build/Droplet+Setup.swift.o:/tmp/build_9e6662da1ad3a4a4089c8520505ca138/.build/release/App.build/Misc/String+E164Format.swift.o:function _::_TTSf4g_n_n___TFC3App14AuthMiddleware7respondfzT2toC4HTTP7Request10chainingToPS1_9Responder(Response) static const: error: undefined reference to '_TFE8VaporJWTPS_16ClaimsVerifiable12verifyClaimsfGSaPS_5Claim(bool) static'
remote: /tmp/build_9e6662da1ad3a4a4089c8520505ca138/.build/release/App.build/Droplet+Setup.swift.o:/tmp/build_9e6662da1ad3a4a4089c8520505ca138/.build/release/App.build/Misc/String+E164Format.swift.o:function _::_TTSf4g_n_n___TFC3App14AuthMiddleware7respondfzT2toC4HTTP7Request10chainingToPS1_9Responder(Response) static const: error: undefined reference to '_TFE8VaporJWTPS_16ClaimsVerifiable12verifyClaimsfGSaPS_5Claim(bool) static'
remote: /tmp/build_9e6662da1ad3a4a4089c8520505ca138/.build/release/App.build/RenewalTokenMiddleware.swift.o:/tmp/build_9e6662da1ad3a4a4089c8520505ca138/.build/release/App.build/Misc/String+E164Format.swift.o:function _::_TTSf4g_n_n___TFC3App22RenewalTokenMiddleware7respondfzT2toC4HTTP7Request10chainingToPS1_9Responder(Response) static const: error: undefined reference to '_TFE8VaporJWTPS_16ClaimsVerifiable12verifyClaimsfGSaPS_5Claim(bool) static'
remote: clang-3.7: error: linker command failed with exit code 1 (use -v to see invocation)
remote: :0: error: link command failed with exit code 1 (use -v to see invocation)
remote: :0: error: build had 1 command failures

it runs locally on mac with no issue, any ideas?

In Ubuntu 14.04.2 run Error

I used vapor-jwt run heroku have no problem. but I used in Ubuntu 14.04.2 run error.
information:
execute this line.
let jwt = try JWT(payload: Node(ExpirationTimeClaim(Date() + 60)), signer: HS256(key: "secret"))

*** Error in `.build/debug/App': free(): invalid next size (fast): 0x00007f3544013fe0 ***

Playgrounds failing

Playground execution is failing with the following message:
Playground execution failed: error: missing required module 'CTLS'

I get the same error in an unrelated project but with CSQLite, another C based module mapped to swift. It seems these kind of modules don't work well with playgrounds anymore. Does anyone know a solution?

Including this causes errors with vapor fetch, pointing to crypto.git

I just added this to my Package.swift and did a vapor clean; vapor fetch and got the following.

Charlies-Air:GotYourBackServer charlie$ vapor clean
Cleaning [Done]
Charlies-Air:GotYourBackServer charlie$ vapor fetch
No Packages folder, fetch may take a while...
Fetching Dependencies [Failed]
Error: /usr/bin/git clone --recursive --depth 10 https://github.com/vapor/Crypto.git /Users/charlie/GotYourBackServer/Packages/Crypto.git
fatal: destination path '/Users/charlie/GotYourBackServer/Packages/Crypto.git' already exists and is not an empty directory.

swift-package: error: Failed to clone https://github.com/vapor/Crypto.git to /Users/charlie/GotYourBackServer/Packages/Crypto.git

Any thoughts on how to resolve this?

Missing RSA Encryption Algorithms

As of the current state of the beta branch, only the HMAC algorithms have been implemented. There should also be implementations for the RSA algorithms.

Proper way to get userId from token

Hi, what would be the prefered way to retrieve the userId from the token? I don't want to validate a userId claim against a known Id but extract the id from the token.

Extraneous padding added by BytesTranscoder causes JWT decoding to fail

When decoding a JWT from a string, I get this error :

▿ Jay.JayError.extraTokensFound
  ▿ extraTokensFound: Jay.ByteReader #0
    ▿ content: 28 elements
      - 123
      - 34
      - 116
      - 121
      - 112
      - 34
      - 58
      - 34
      - 74
      - 87
      - 84
      - 34
      - 44
      - 34
      - 97
      - 108
      - 103
      - 34
      - 58
      - 34
      - 72
      - 83
      - 50
      - 53
      - 54
      - 34
      - 125
      - 0
    - cursor: 27

The JWT was eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.(...).(...).

This only happens when a Base64URL-encoded segment has n characters, where n % 4 = 0.

After investigating the issue, I've noticed that BytesTranscoder adds a 4 characters-long padding in such cases when converting to Base64 (for example, "abcd" becomes "abcd====" and eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9 becomes eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9====).

This extra padding then interpreted as a null byte by Data(base64Encoded:). But according to Wikipedia, when n % 4 = 0 no padding characters should be added.

EC key specification

Maybe a cursory look at the code wasn't enough, but where do I plug in my private EC key for signing the message?

Crash in base64 encoder for Swift 3.1 release builds.

App crashes in Base64URLTranscoder.base64URLEncode() for release builds only, works fine in Xcode. Crash log attached.

OS X version: 10.12.4
Xcode version: 8.3
Swift version: Apple Swift version 3.1 (swiftlang-802.0.48 clang-802.0.38)

Packages.swift:

.Package(url: "https://github.com/qutheory/vapor.git", majorVersion: 1),
.Package(url: "https://github.com/vapor/jwt.git", majorVersion: 1),

Packages.pins:

{
  "package": "Vapor",
  "reason": null,
  "repositoryURL": "https://github.com/qutheory/vapor.git",
  "version": "1.5.13"
},
{
  "package": "JWT",
  "reason": null,
  "repositoryURL": "https://github.com/vapor/jwt.git",
  "version": "1.0.0"
},

App_2017-04-03-162901_fdr.crash.txt

Documentation request.

I couldn't find documentation on JWT 4.

It would be very helpful if someone provide some documentation or some example codes about Vapor 4 + JWT 4.

Token validate is always return True

HI man, i just newbie from swift and web service, would you tell me why i am always got true on token validate, this is my code

let jwt = try JWT(payload: Node(ExpirationTimeClaim(Date() + 1)),signer: HS256(key: "secret"))
return try JSON(node: [ "error_code" : "0", "token" : jwt.createToken(), "valid" : "60 second"])

and then i call isValidate like you did :

let jwt3 = try JWT(token: token)
let isValid = try jwt3.verifySignatureWith(HS256(key: "secret"))
if (isValid==false){
return try JSON(node: [ "error_code" : "1000", "message" : "Token is expired" ])
}

thanks man

nicer RSA failure errors

RSA signing can fail if the key is not large enough (for instance 256 or 512). The return code of the RSA_sign method should be checked and a more helpful error should be thrown.

Token Verification Can Generate Incorrect Message

Currently when verifying a token the message is rebuilt from the header and payload nodes via createMessage(). This only produces the correct message when the original JSON is ordered and minified in the exact same way, otherwise a malformed message is produced and verification will fail.

Example (https://jwt.io)

Source Header:

{ 
  "alg": "HS256",
  "typ": "JWT"
}

Source Payload:

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

Source Header Minified:

{"alg":"HS256","typ":"JWT"}

Source Payload Minified:

{"sub":"1234567890","name":"John Doe","admin":true}

Source Message:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9

VaporJWT Reconstructed Header:

{"alg":"HS256","typ":"JWT"}

VaporJWT Reconstructed Payload: (different than source)

{"admin":true,"name":"John Doe","sub":"1234567890"}

VaporJWT Reconstructed Message: (different than source)
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhZG1pbiI6dHJ1ZSwibmFtZSI6IkpvaG4gRG9lIiwic3ViIjoiMTIzNDU2Nzg5MCJ9

Compile error CTLS module

Hi, I can't build a newly downloaded version of master on my mac :

.../jwt-master-2/Packages/CTLS-0.1.1/shim.h:4:10: 'openssl/conf.h' file not found
.../jwt-master-2/Packages/Crypto-2.0.0-alpha.4/Sources/Crypto/Cipher/Cipher+Method.swift:1:8: Could not build Objective-C module 'CTLS'

NB : I did got it working couple weeks ago !

Headers causing issues

Here's repro code from user, this will not work, if you remove headers, it will. This can be used to create a repro case and fix:

let expiry = Date() + 1800
        let headers: JSON = JSON(["aaaa": "bbbb", "cccc": 1])
        let payload = JSON([
            ExpirationTimeClaim(date: expiry)
        ])
        let jwt = try JWT(headers: headers, payload: payload, signer: HS512(key: "secret".bytes))
        let token = try jwt.createToken()
        
        
        let receivedJWT = try JWT(token: token)
        do {
            try receivedJWT.verifySignature(using: HS512(key: "secret".bytes))
            try receivedJWT.verifyClaims([ExpirationTimeClaim(date: Date())])
        }
        catch {
            print(error)
        }

Remove encodings

Seems that JWTs should always be base 64 url encoded as per the RFC:

   JWTs encode claims to be transmitted as a JSON
   object (as defined in RFC 4627 [RFC4627]) that is base64url encoded
   and digitally signed or HMACed and/or encrypted.

Perhaps we should remove the encoding types to reduce the possibility of errors (as can happen when trying to parse tokens from JWT.io without explicitly specifying the base64urlencoding)

Carthage support

Wanted to play with this, please fix issues to support carthage.

integrate JWTKit with Vapor

Developers who want to create protected routes using JWTs reasonably look towards Auth and to this package (JWT). Currently, though, the two cannot work with one another. Most of the pieces are in place, but they lack an easy-to-use integration layer.

Auth is the starting point by providing TokenAuthenticatable and TokenAuthenticationMiddleware which both use an associated TokenType which must conform to Token.

This package provides a concrete JWT type but since it doesn't conform to Token it is ineligible to use currently as a TokenType.

I'm not entirely sure what the missing pieces are or should be, but @anthonycastelli shared with me an implementation, that while it didn't leverage the pieces from Auth, does outline a good starting point by creating a JWTMiddleware and JWTService (as well as an app-specific JWTPayload to be used in a JWT).

Sporadic failure of ES256

The patch in #102 introduced a subtle bug: In case where the r or s value of the signature is a "small" number, BN_bn2bin will actually produce less than 32 bytes per value. In this case some 0 padding is necessary to make sure that the final signature is 2 x 32 = 64 bytes long. See eg: kylebrowning/APNSwift#48

Could not create public key from x509Cert

[JWT.JWTError: JWT error: Could not create public key]

I am attempting to validate the signature of a web token I have received from a third party service (Microsoft) using the following.

let signer = try RS256(x509Cert: cert[0].bytes)
try jwt.verifySignature(using: signer)

Where cert[0] is a string representation of the certificate that is retrieved from a jwk(JSON object).

I am unable to create the public key using this method and without much documentation to go on I haven't been able to determine if I am doing this incorrectly or not. Any help would be much appreciated.

Audience Claim is an array - causing rejection from Firebase

This may or may not be a general issue, but raising it for visibility.

When authenticating with Firebase, you use a JWT generated on Vapor, passed to the mobile app, and then passed to Firebase. Documentation of the process and JWT specification can be found here.

Problem:

JWT Payload:

{
  "iss": "[email protected]",
  "aud": [
    "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit"
  ],
  "iat": 1499885888,
  "exp": 1499888888,
  "sub": "[email protected]",
  "uid": "xxxxxxxx"
}

When authenticating with Firebase from my iOS app with this JWT payload, I was receiving this error:

ERROR: Optional(Error Domain=FIRAuthErrorDomain Code=17000 "The custom token format is incorrect. Please check the documentation." UserInfo={NSLocalizedDescription=The custom token format is incorrect. Please check the documentation., error_name=ERROR_INVALID_CUSTOM_TOKEN})

The incorrect format was due to the aud field being an array, not a single string.

Solution:

I solved this by creating a custom claim:

struct SingleAudienceClaim: EqualityClaim {
    public static var name = "aud"
    public let value: String

    init(string: String) {
        self.value = string
    }

    public init?(_ node: Node) {
        guard let string = node.string else {
            return nil
        }

        self.init(string: string)
    }

    public var node: Node {
        return .string(value)
    }
}

I'm new to using JWT (and server-side in general), so not certain if this simply is a very specific issue with Firebase, or may reoccur across other sources.

Another solution could be the make the naming of AudienceClaim more explicit that it is for multiple audience values?

Dependency graph could not be satisfied

When i add the new vapor/jwt package:
.Package(url:"https://github.com/vapor/jwt.git", majorVersion: 0)
to my Package.swift, vapor xcode gives error:
swift-package: error: The dependency graph could not be satisfied (https://github.com/vapor/crypto.git)
Thoughts?

Certificate based RSA public key creation.

Would be nice to have a way to create a key from a certificate containing a public key. Its not easily doable as of now because the initializes of the RSxxx classes require Bytes input. The following code is possible with #45

extension RSASigner {
    
    init(certificate: String) throws {
        let certificateBytes = certificate.bytes
        
        let cert_bio = BIO_new_mem_buf(certificateBytes, Int32(certificateBytes.count))
        var _cert: UnsafeMutablePointer<X509>?
        PEM_read_bio_X509(cert_bio, &_cert, nil, nil)
        
        guard let cert = _cert else {
            throw Abort.custom(status: .internalServerError, message: "Failed to decode certificate.")
        }
        
        guard let publicKey = X509_get_pubkey(cert) else {
            throw Abort.custom(status: .internalServerError, message: "Failed to decode public key.")
        }
        
        guard let rsa = EVP_PKEY_get1_RSA(publicKey) else {
            throw Abort.custom(status: .internalServerError, message: "Failed to get rsa key.")
        }
        
        self.init(key: .public(rsa))
    }
}

Support for Swift 2.1

Hi ,
can you please provide version of lib that support swift 2.1 ? It would be of G8 help !

Working example with ES256

Hi Siemen, very nice library.
Do you have by any chance a working example with a ES256 signing?
I tried reproducing your steps below with secp521r1 in the keys generation and built the JWT with the private one and verified the signature with the public key. Unfortunately I get a (VaporJWT.JWTError error 1.)

This is my implementation:

    guard let privateKey = drop.config["keys","jwtPrivateKey"]?.string else{
        throw Abort.custom(status: .badRequest, message: "The private key is not set")
    }
    
    guard let publicKey = drop.config["keys","jwtPublicKey"]?.string else{
        throw Abort.custom(status: .badRequest, message: "The public key is not set")
    }
    
    do {
        let jwt = try JWT(payload: Node(ExpirationTimeClaim(Date() + 3600)),
                          signer: ES256(key: publicKey))
        let token = try jwt.createToken()
        print(token)
    } catch{
        print(error.localizedDescription)
    }
    
    do {
        let jwt = try JWT(token: bearer.string)
        let isValid = try jwt.verifySignatureWith(ES256(key: privateKey))
        print(isValid)
        print(bearer)
    } catch {
        print(error.localizedDescription)
    }`

Any insight on that? Thanks a lot.

PS: The example works correctly if I use a HS256 signature.

JWK Verification

Apparently the JWT 3 doesn't support JWK signing yet. This would be a good feature to implement, especially for those of us that used it in Vapor 2 🙂.

'&' used with non-inout argument of type 'JWT<_>'

There seems to be a problem with the latest version 3.0.0 and Swift 4.1

I get this error when compiling on Mac:

.../.build/checkouts/JWTVapor.git--6738815433567181283/Sources/JWTVapor/JWTService.swift:20:36: error: '&' used with non-inout argument of type 'JWT<_>'
        let data = try signer.sign(&jwt)

I think jwt is not an inout, can the & be removed?

RSA public/private key

Unless I'm mistaken, the RSA signers should have a separate public and private key. The private key is used for signing and the public key is used for verifying the signature.

Right now you can only add one key that is used for both.

Error when creating a public signer for certificates

Looking at old commits (pre v4) there was added support for certificates. Is this in version 4?

I'm trying to use these google certs:
https://www.googleapis.com/robot/v1/metadata/x509/[email protected]

With this code: (ignore the hard code for testing!)

let publicKey = certs["f5c9aebe234da6016bd7b949168b8cd5b4ec9eeb"]!
let publicSigner = try JWTSigner.rs256(key: .public(pem: publicKey.bytes))

I get the following error when creating a public signer.
Fatal error: Error raised at top level: JWTKit error: signing algorithm error: bioConversionFailure: file /AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-1103.8.25.8/swift/stdlib/public/core/ErrorType.swift, line 200 2020-05-16 20:07:25.947242-0700 Run[9217:3171678] Fatal error: Error raised at top level: JWTKit error: signing algorithm error: bioConversionFailure: file /AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-1103.8.25.8/swift/stdlib/public/core/ErrorType.swift, line 200

Thanks!

error: undefined reference to '_TFE3JWTPS_9RSASignerCfzT8x509CertGSaVs5UInt8(long long)'

I'm getting a linking error on linux complaining about the new x509 method.

let certificate = try self.fetchSigningKey(for: keyId).extractRSACertificate()
let signer = try RS256(x509Cert: certificate)

Linking ./.build/release/App
/home/xxx/.build/release/App.build/Collections/AuthenticationCollection.swift.o:/home/xxx/.build/release/App.build/Stripe/Models/Invoice/Invoice.swift.o:function TFFC3App24AuthenticationCollection5buildFP7Routing12RouteBuilder_T_U0_FzC4HTTP7RequestPS3_21ResponseRepresentable: error: undefined reference to '_TFE3JWTPS_9RSASignerCfzT8x509CertGSaVs5UInt8(long long)'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
:0: error: link command failed with exit code 1 (use -v to see invocation)
:0: error: build had 1 command failures
error: exit(1): /home/xxx/.swiftenv/versions/3.1/usr/bin/swift-build-tool -f /home/xxx/.build/release.yaml
Building Project [Failed]
Error: execute(1)

Vapor 2.0.3
JWT 2.1.0

Allow `IssuedAtClaim` to compare dates

I'm using Firebase to manage my users, and I use this library to validate JWT tokens sent by Firebase. In their documentation, they state that I must validate that the Issued-at time is in the past. I don't think I can do this with the current implementation, as IssuedAtClaim forces comparison to a specific time.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.