...
Source file
src/github.com/ory/fosite/client_authentication_jwks_strategy.go
1
21
22 package fosite
23
24 import (
25 "encoding/json"
26 "net/http"
27 "sync"
28
29 "github.com/ory/x/errorsx"
30
31 jose "gopkg.in/square/go-jose.v2"
32 )
33
34
35
36 type JWKSFetcherStrategy interface {
37
38
39
40 Resolve(location string, forceRefresh bool) (*jose.JSONWebKeySet, error)
41 }
42
43 type DefaultJWKSFetcherStrategy struct {
44 client *http.Client
45 keys map[string]jose.JSONWebKeySet
46 sync.Mutex
47 }
48
49 func NewDefaultJWKSFetcherStrategy() JWKSFetcherStrategy {
50 return &DefaultJWKSFetcherStrategy{
51 keys: make(map[string]jose.JSONWebKeySet),
52 client: http.DefaultClient,
53 }
54 }
55
56 func (s *DefaultJWKSFetcherStrategy) Resolve(location string, forceRefresh bool) (*jose.JSONWebKeySet, error) {
57 s.Lock()
58 defer s.Unlock()
59
60 keys, ok := s.keys[location]
61 if !ok || forceRefresh {
62 response, err := s.client.Get(location)
63 if err != nil {
64 return nil, errorsx.WithStack(ErrServerError.WithHintf("Unable to fetch JSON Web Keys from location '%s'. Check for typos or other network issues.", location).WithWrap(err).WithDebug(err.Error()))
65 }
66 defer response.Body.Close()
67
68 if response.StatusCode < 200 || response.StatusCode >= 400 {
69 return nil, errorsx.WithStack(ErrServerError.WithHintf("Expected successful status code in range of 200 - 399 from location '%s' but received code %d.", location, response.StatusCode))
70 }
71
72 var set jose.JSONWebKeySet
73 if err := json.NewDecoder(response.Body).Decode(&set); err != nil {
74 return nil, errorsx.WithStack(ErrServerError.WithHintf("Unable to decode JSON Web Keys from location '%s'. Please check for typos and if the URL returns valid JSON.", location).WithWrap(err).WithDebug(err.Error()))
75 }
76
77 s.keys[location] = set
78 return &set, nil
79 }
80
81 return &keys, nil
82 }
83
View as plain text