Skip to content

Commit

Permalink
support for providing RSA private key to parser
Browse files Browse the repository at this point in the history
  • Loading branch information
evgenyk committed May 16, 2024
1 parent 9ce91e9 commit 52e22b3
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 4 deletions.
11 changes: 7 additions & 4 deletions jwt/jwt.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package jwt

import (
"crypto/rsa"
"fmt"
"net/http"
"slices"
Expand All @@ -25,6 +26,7 @@ type Token struct {
isValid bool
}

// ParseFromAuthorizationHeader will parse the token from the Authorization header and validate it with the given options.
func ParseFromAuthorizationHeader(r *http.Request, options ...func(*Token)) (*Token, error) {
requestedToken := r.Header.Get("Authorization")
splitToken := strings.Split(requestedToken, "Bearer")
Expand All @@ -35,6 +37,7 @@ func ParseFromAuthorizationHeader(r *http.Request, options ...func(*Token)) (*To
return ParseOAuth2Token(&oauth2.Token{AccessToken: requestedToken}, options...)
}

// ParseFromString will parse the given token and validate it with the given options.
func ParseFromString(rawToken string, options ...func(*Token)) (*Token, error) {
return ParseOAuth2Token(&oauth2.Token{AccessToken: rawToken}, options...)
}
Expand Down Expand Up @@ -93,8 +96,8 @@ func (j *Token) IsValid() bool {
return j.isValid
}

// WillValidateKeys will validate the token with the given keyFunc.
func WillValidateKeys(keyFunc func(rawToken string) (interface{}, error)) func(*Token) {
// WillValidateKeys receives a token and needs to return a public rsa key to validate the token.
func WillValidateKeys(keyFunc func(rawToken string) (*rsa.PublicKey, error)) func(*Token) {
return func(s *Token) {
wrapped := func(token *golangjwt.Token) (interface{}, error) {
return keyFunc(token.Raw)
Expand All @@ -104,9 +107,9 @@ func WillValidateKeys(keyFunc func(rawToken string) (interface{}, error)) func(*
}

// WillValidateKeys will validate the token with the given keyFunc.
func WillValidateJWKSUrl(jwks string) func(*Token) {
func WillValidateJWKSUrl(url string) func(*Token) {
return func(s *Token) {
jwks, err := keyfunc.NewDefault([]string{jwks})
jwks, err := keyfunc.NewDefault([]string{url})
if err != nil {
return
}
Expand Down
28 changes: 28 additions & 0 deletions oauth2/authorization_code/authorization_code_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ package authorization_code

import (
"context"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"fmt"
"io"
"net/http"
Expand Down Expand Up @@ -46,6 +49,17 @@ func TestAutorizationCodeFlowOnline(t *testing.T) {
assert.Nil(t, err, "error parsing token")
assert.True(t, parsedToken.IsValid(), "token is not valid")

parsedToken, err = jwt.ParseFromAuthorizationHeader(r,
//testing verification with provided private key instead of JWKS
jwt.WillValidateKeys(func(rawToken string) (*rsa.PublicKey, error) {
return testPublicPEM(), nil
}),
jwt.WillValidateAudience("http://my.api.com/api"),
jwt.WillValidateAlgorythm(),
)
assert.Nil(t, err, "error parsing token")
assert.True(t, parsedToken.IsValid(), "token is not valid")

w.Write([]byte(`hello world`))
}))
defer testApiServer.Close()
Expand Down Expand Up @@ -133,7 +147,21 @@ func testJWKSPublicKeys() []byte {
]}`

return []byte(key)
}

func testPublicPEM() *rsa.PublicKey {
publicKey := `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuOaDKcdR8JR7PiVEHjRO
1dQVbLFoMRSiBio+rRlq+ljouBFJtehghnkIk0sSJlmoJY8329RdF9122IL0NYxO
+QTFJmAamSdUcmSgg4D3qI3Nc82H7L7ocad2OfhhXmBwz+O/8cxK+xYAnvKGmHf/
tSmqVWJVbvBFG1r7sU3WBfLZPoivofFKjnhPG5jFbC2AziTFqKiQ7i2T2F0APIPT
J5Bf05zI2BpIYwyZyaP1F5EWmBEOvOP02Mr0L3Rj0lOJGQJ8gJh9uacGCt/RZAlx
0ZMiK93fk3vfszfKv0UhOpYKBcElR/5U1gJfXuDF6j10vG+8rwoorIPzCwu3wKZP
ewIDAQAB
-----END PUBLIC KEY-----`
block, _ := pem.Decode([]byte(publicKey))
pemKey, _ := x509.ParsePKIXPublicKey(block.Bytes)
return pemKey.(*rsa.PublicKey)
}

func testJWKSPrivateKey() string {
Expand Down

0 comments on commit 52e22b3

Please sign in to comment.