github.com/hellofresh/janus@v0.0.0-20230925145208-ce8de8183c67/pkg/plugin/oauth2/oauth_introspection.go (about) 1 package oauth2 2 3 import ( 4 "context" 5 "encoding/json" 6 "fmt" 7 "net/http" 8 "net/url" 9 10 log "github.com/sirupsen/logrus" 11 12 "github.com/hellofresh/janus/pkg/proxy" 13 "github.com/hellofresh/janus/pkg/proxy/balancer" 14 ) 15 16 type oAuthResponse struct { 17 Active bool `json:"active"` 18 } 19 20 // IntrospectionManager is responsible for using OAuth2 Introspection definition to 21 // validate tokens from an authentication provider 22 type IntrospectionManager struct { 23 balancer balancer.Balancer 24 urls proxy.Targets 25 settings *IntrospectionSettings 26 } 27 28 // NewIntrospectionManager creates a new instance of Introspection 29 func NewIntrospectionManager(def *proxy.Definition, settings *IntrospectionSettings) (*IntrospectionManager, error) { 30 bb, err := balancer.New(def.Upstreams.Balancing) 31 if err != nil { 32 return nil, fmt.Errorf("could not create a bb: %w", err) 33 } 34 35 return &IntrospectionManager{bb, def.Upstreams.Targets, settings}, nil 36 } 37 38 // IsKeyAuthorized checks if the access token is valid 39 func (o *IntrospectionManager) IsKeyAuthorized(ctx context.Context, accessToken string) bool { 40 resp, err := o.doStatusRequest(accessToken) 41 defer resp.Body.Close() 42 43 if err != nil { 44 log.WithError(err). 45 Error("Error making a request to the authentication provider") 46 } 47 48 if resp.StatusCode != http.StatusOK { 49 log.Info("The token check was invalid") 50 return false 51 } 52 53 var oauthResp oAuthResponse 54 decoder := json.NewDecoder(resp.Body) 55 err = decoder.Decode(&oauthResp) 56 if err != nil { 57 return false 58 } 59 60 return oauthResp.Active 61 } 62 63 func (o *IntrospectionManager) doStatusRequest(accessToken string) (*http.Response, error) { 64 upstream, err := o.balancer.Elect(o.urls.ToBalancerTargets()) 65 if err != nil { 66 return nil, fmt.Errorf("could not elect one upstream: %w", err) 67 } 68 69 req, err := http.NewRequest(http.MethodGet, upstream.Target, nil) 70 if err != nil { 71 log.WithError(err).Error("Creating the request for the health check failed") 72 return nil, err 73 } 74 75 if o.settings.UseAuthHeader { 76 req.Header.Add("Authorization", fmt.Sprintf("%s %s", o.settings.AuthHeaderType, accessToken)) 77 } else if o.settings.UseCustomHeader { 78 req.Header.Add(o.settings.HeaderName, accessToken) 79 } else { 80 req.Form = make(url.Values) 81 req.Form.Add(o.settings.ParamName, accessToken) 82 } 83 84 // Inform to close the connection after the transaction is complete 85 req.Header.Set("Connection", "close") 86 87 resp, err := http.DefaultClient.Do(req) 88 if err != nil { 89 log.WithError(err).Error("Making the request for the health check failed") 90 return resp, err 91 } 92 93 return resp, err 94 }