forked from krakend/krakend-jose
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathjwk_client.go
92 lines (76 loc) · 2.75 KB
/
jwk_client.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package jose
import (
"net/http"
"github.com/auth0-community/go-auth0"
"gopkg.in/square/go-jose.v2/jwt"
)
//TokenIDGetter extracts the keyID from the JSON web token
type TokenIDGetter interface {
Get(*jwt.JSONWebToken) string
}
//TokenKeyIDGetterFunc function conforming
// to the TokenIDGetter interface.
type TokenKeyIDGetterFunc func(*jwt.JSONWebToken) string
// Extract calls f(r)
func (f TokenKeyIDGetterFunc) Get(token *jwt.JSONWebToken) string {
return f(token)
}
//DefaultTokenKeyIDGetter returns the default kid as the JSONWebKey key id
func DefaultTokenKeyIDGetter(token *jwt.JSONWebToken) string {
return token.Headers[0].KeyID
}
//X5TTokenKeyIDGetter extracts the key id from the jSONWebToken as the x5t
func X5TTokenKeyIDGetter(token *jwt.JSONWebToken) string {
x5t, ok := token.Headers[0].ExtraHeaders["x5t"].(string)
if !ok {
return token.Headers[0].KeyID
}
return x5t
}
//CompoundX5TTokenKeyIDGetter extracts the key id from the jSONWebToken as a compound string of the kid and x5t
func CompoundX5TTokenKeyIDGetter(token *jwt.JSONWebToken) string {
return token.Headers[0].KeyID + X5TTokenKeyIDGetter(token)
}
//TokenIDGetterFactory returns the TokenIDGetter from the keyIdentifyStrategy configuration string
func TokenIDGetterFactory(keyIdentifyStrategy string) TokenIDGetter {
var supportedKeyIdentifyStrategy = map[string]TokenKeyIDGetterFunc{
"kid": DefaultTokenKeyIDGetter,
"x5t": X5TTokenKeyIDGetter,
"kid_x5t": CompoundX5TTokenKeyIDGetter,
}
if tokenGetter, ok := supportedKeyIdentifyStrategy[keyIdentifyStrategy]; ok {
return tokenGetter
}
return TokenKeyIDGetterFunc(DefaultTokenKeyIDGetter)
}
type JWKClientOptions struct {
auth0.JWKClientOptions
KeyIdentifyStrategy string
}
type JWKClient struct {
*auth0.JWKClient
extractor auth0.RequestTokenExtractor
tokenIDGetter TokenIDGetter
}
// NewJWKClientWithCache creates a new JWKClient instance from the provided options and custom extractor and keycacher.
// Passing nil to keyCacher will create a persistent key cacher.
// the extractor is also saved in the extended JWKClient.
func NewJWKClientWithCache(options JWKClientOptions, extractor auth0.RequestTokenExtractor, keyCacher auth0.KeyCacher) *JWKClient {
return &JWKClient{
JWKClient: auth0.NewJWKClientWithCache(options.JWKClientOptions, extractor, keyCacher),
extractor: extractor,
tokenIDGetter: TokenIDGetterFactory(options.KeyIdentifyStrategy),
}
}
// GetSecret implements the GetSecret method of the SecretProvider interface.
func (j *JWKClient) GetSecret(r *http.Request) (interface{}, error) {
token, err := j.extractor.Extract(r)
if err != nil {
return nil, err
}
if len(token.Headers) < 1 {
return nil, auth0.ErrNoJWTHeaders
}
keyID := j.tokenIDGetter.Get(token)
return j.GetKey(keyID)
}