Skip to content
This repository has been archived by the owner on Feb 27, 2023. It is now read-only.

Commit

Permalink
Merge branch 'shaxbee-v2' into v2
Browse files Browse the repository at this point in the history
* shaxbee-v2:
  Return key from tryJWKS instead of using pointer
  Allow using JSONWebKeySet to get claims or decrypt nested token
  • Loading branch information
csstaub committed Feb 21, 2019
2 parents 095479d + f1cd754 commit 32a0071
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 5 deletions.
39 changes: 35 additions & 4 deletions jwt/jwt.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ package jwt

import (
"fmt"
"gopkg.in/square/go-jose.v2"
"gopkg.in/square/go-jose.v2/json"
"strings"

jose "gopkg.in/square/go-jose.v2"
"gopkg.in/square/go-jose.v2/json"
)

// JSONWebToken represents a JSON Web Token (as specified in RFC7519).
Expand All @@ -38,7 +39,9 @@ type NestedJSONWebToken struct {

// Claims deserializes a JSONWebToken into dest using the provided key.
func (t *JSONWebToken) Claims(key interface{}, dest ...interface{}) error {
b, err := t.payload(key)
payloadKey := tryJWKS(t.Headers, key)

b, err := t.payload(payloadKey)
if err != nil {
return err
}
Expand Down Expand Up @@ -69,7 +72,9 @@ func (t *JSONWebToken) UnsafeClaimsWithoutVerification(dest ...interface{}) erro
}

func (t *NestedJSONWebToken) Decrypt(decryptionKey interface{}) (*JSONWebToken, error) {
b, err := t.enc.Decrypt(decryptionKey)
key := tryJWKS(t.Headers, decryptionKey)

b, err := t.enc.Decrypt(key)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -130,3 +135,29 @@ func ParseSignedAndEncrypted(s string) (*NestedJSONWebToken, error) {
Headers: []jose.Header{enc.Header},
}, nil
}

func tryJWKS(headers []jose.Header, key interface{}) interface{} {
jwks, ok := key.(*jose.JSONWebKeySet)
if !ok {
return key
}

var kid string
for _, header := range headers {
if header.KeyID != "" {
kid = header.KeyID
break
}
}

if kid == "" {
return key
}

keys := jwks.Key(kid)
if len(keys) == 0 {
return key
}

return keys[0].Key
}
26 changes: 25 additions & 1 deletion jwt/jwt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@ import (
"testing"

"github.com/stretchr/testify/assert"
"gopkg.in/square/go-jose.v2"
jose "gopkg.in/square/go-jose.v2"
)

var (
hmacSignedToken = `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJzdWJqZWN0IiwiaXNzIjoiaXNzdWVyIiwic2NvcGVzIjpbInMxIiwiczIiXX0.Y6_PfQHrzRJ_Vlxij5VI07-pgDIuJNN3Z_g5sSaGQ0c`
rsaSignedToken = `eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJpc3N1ZXIiLCJzY29wZXMiOlsiczEiLCJzMiJdLCJzdWIiOiJzdWJqZWN0In0.UDDtyK9gC9kyHltcP7E_XODsnqcJWZIiXeGmSAH7SE9YKy3N0KSfFIN85dCNjTfs6zvy4rkrCHzLB7uKAtzMearh3q7jL4nxbhUMhlUcs_9QDVoN4q_j58XmRqBqRnBk-RmDu9TgcV8RbErP4awpIhwWb5UU-hR__4_iNbHdKqwSUPDKYGlf5eicuiYrPxH8mxivk4LRD-vyRdBZZKBt0XIDnEU4TdcNCzAXojkftqcFWYsczwS8R4JHd1qYsMyiaWl4trdHZkO4QkeLe34z4ZAaPMt3wE-gcU-VoqYTGxz-K3Le2VaZ0r3j_z6bOInsv0yngC_cD1dCXMyQJWnWjQ`
rsaSignedTokenWithKid = `eyJhbGciOiJSUzI1NiIsImtpZCI6ImZvb2JhciJ9.eyJpc3MiOiJpc3N1ZXIiLCJzY29wZXMiOlsiczEiLCJzMiJdLCJzdWIiOiJzdWJqZWN0In0.RxZhTRfPDb6UJ58FwvC89GgJGC8lAO04tz5iLlBpIJsyPZB0X_UgXSj0SGVFm2jbP_i-ZVH4HFC2fMB1n-so9CnCOpunWwhYNdgF6ewQJ0ADTWwfDGsK12UOmyT2naaZN8ZUBF8cgPtOgdWqQjk2Ng9QFRJxlUuKYczBp7vjWvgX8WMwQcaA-eK7HtguR4e9c4FMbeFK8Soc4jCsVTjIKdSn9SErc42gFu65NI1hZ3OPe_T7AZqdDjCkJpoiJ65GdD_qvGkVndJSEcMp3riXQpAy0JbctVkYecdFaGidbxHRrdcQYHtKn-XGMCh2uoBKleUr1fTMiyCGPQQesy3xHw`
invalidPayloadSignedToken = `eyJhbGciOiJIUzI1NiJ9.aW52YWxpZC1wYXlsb2Fk.ScBKKm18jcaMLGYDNRUqB5gVMRZl4DM6dh3ShcxeNgY`
invalidPartsSignedToken = `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJzdWJqZWN0IiwiaXNzIjoiaXNzdWVyIiwic2NvcGVzIjpbInMxIiwiczIiXX0`
hmacEncryptedToken = `eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4R0NNIn0..NZrU98U4QNO0y-u6.HSq5CvlmkUT1BPqLGZ4.1-zuiZ4RbHrTTUoA8Dvfhg`
Expand Down Expand Up @@ -67,6 +68,29 @@ func TestGetClaimsWithoutVerification(t *testing.T) {
}
}

func TestDecodeTokenWithJWKS(t *testing.T) {
jwks := &jose.JSONWebKeySet{
Keys: []jose.JSONWebKey{
{
KeyID: "foobar",
Key: &testPrivRSAKey1.PublicKey,
},
},
}

tok, err := ParseSigned(rsaSignedTokenWithKid)
if assert.NoError(t, err, "Error parsing signed token.") {
cl := make(map[string]interface{})
if assert.NoError(t, tok.Claims(jwks, &cl)) {
assert.Equal(t, map[string]interface{}{
"sub": "subject",
"iss": "issuer",
"scopes": []interface{}{"s1", "s2"},
}, cl)
}
}
}

func TestDecodeToken(t *testing.T) {
tok, err := ParseSigned(hmacSignedToken)
if assert.NoError(t, err, "Error parsing signed token.") {
Expand Down

0 comments on commit 32a0071

Please sign in to comment.