From 544326a4b7b95683d6be31f6224c561c4138fa18 Mon Sep 17 00:00:00 2001 From: William Petit Date: Thu, 23 May 2024 15:17:05 +0200 Subject: [PATCH] feat(authn-oidc): use full urls for login callback/logout options --- internal/config/layers.go | 18 ++- internal/config/proxy_server.go | 34 ++++- .../layer/authn/oidc/authenticator.go | 138 ++++++++++++++---- .../proxy/director/layer/authn/oidc/client.go | 3 + .../layer/authn/oidc/client_options.go | 11 +- .../layer/authn/oidc/layer-options.json | 29 +++- .../proxy/director/layer/authn/oidc/layer.go | 9 +- .../layer/authn/oidc/layer_options.go | 20 ++- .../director/layer/authn/oidc/options.go | 38 +++++ internal/proxy/server.go | 22 +-- internal/setup/authn_oidc_layer.go | 10 +- 11 files changed, 270 insertions(+), 62 deletions(-) create mode 100644 internal/proxy/director/layer/authn/oidc/options.go diff --git a/internal/config/layers.go b/internal/config/layers.go index ad3d2dd..b909aae 100644 --- a/internal/config/layers.go +++ b/internal/config/layers.go @@ -15,6 +15,12 @@ func NewDefaultLayersConfig() LayersConfig { }, Authn: AuthnLayerConfig{ TemplateDir: "./layers/authn/templates", + OIDC: AuthnOIDCLayerConfig{ + HTTPClient: AuthnOIDCHTTPClientConfig{ + TransportConfig: NewDefaultTransportConfig(), + Timeout: NewInterpolatedDuration(10 * time.Second), + }, + }, }, } } @@ -25,5 +31,15 @@ type QueueLayerConfig struct { } type AuthnLayerConfig struct { - TemplateDir InterpolatedString `yaml:"templateDir"` + TemplateDir InterpolatedString `yaml:"templateDir"` + OIDC AuthnOIDCLayerConfig `yaml:"oidc"` +} + +type AuthnOIDCLayerConfig struct { + HTTPClient AuthnOIDCHTTPClientConfig `yaml:"httpClient"` +} + +type AuthnOIDCHTTPClientConfig struct { + TransportConfig + Timeout *InterpolatedDuration `yaml:"timeout"` } diff --git a/internal/config/proxy_server.go b/internal/config/proxy_server.go index f4c509a..fa6f5a3 100644 --- a/internal/config/proxy_server.go +++ b/internal/config/proxy_server.go @@ -1,6 +1,10 @@ package config -import "time" +import ( + "crypto/tls" + "net/http" + "time" +) type ProxyServerConfig struct { HTTP HTTPConfig `yaml:"http"` @@ -25,6 +29,33 @@ type TransportConfig struct { WriteBufferSize InterpolatedInt `yaml:"writeBufferSize"` ReadBufferSize InterpolatedInt `yaml:"readBufferSize"` MaxResponseHeaderBytes InterpolatedInt `yaml:"maxResponseHeaderBytes"` + InsecureSkipVerify InterpolatedBool `yaml:"insecureSkipVerify"` +} + +func (c TransportConfig) AsTransport() *http.Transport { + httpTransport := http.DefaultTransport.(*http.Transport).Clone() + + httpTransport.Proxy = http.ProxyFromEnvironment + httpTransport.ForceAttemptHTTP2 = bool(c.ForceAttemptHTTP2) + httpTransport.MaxIdleConns = int(c.MaxIdleConns) + httpTransport.MaxIdleConnsPerHost = int(c.MaxIdleConnsPerHost) + httpTransport.MaxConnsPerHost = int(c.MaxConnsPerHost) + httpTransport.IdleConnTimeout = time.Duration(*c.IdleConnTimeout) + httpTransport.TLSHandshakeTimeout = time.Duration(*c.TLSHandshakeTimeout) + httpTransport.ExpectContinueTimeout = time.Duration(*c.ExpectContinueTimeout) + httpTransport.DisableKeepAlives = bool(c.DisableKeepAlives) + httpTransport.DisableCompression = bool(c.DisableCompression) + httpTransport.ResponseHeaderTimeout = time.Duration(*c.ResponseHeaderTimeout) + httpTransport.WriteBufferSize = int(c.WriteBufferSize) + httpTransport.ReadBufferSize = int(c.ReadBufferSize) + httpTransport.MaxResponseHeaderBytes = int64(c.MaxResponseHeaderBytes) + + if httpTransport.TLSClientConfig == nil { + httpTransport.TLSClientConfig = &tls.Config{} + } + httpTransport.TLSClientConfig.InsecureSkipVerify = bool(c.InsecureSkipVerify) + + return httpTransport } func NewDefaultProxyServerConfig() ProxyServerConfig { @@ -69,5 +100,6 @@ func NewDefaultTransportConfig() TransportConfig { ReadBufferSize: 4096, WriteBufferSize: 4096, MaxResponseHeaderBytes: 0, + InsecureSkipVerify: false, } } diff --git a/internal/proxy/director/layer/authn/oidc/authenticator.go b/internal/proxy/director/layer/authn/oidc/authenticator.go index d4c7b19..3b6994c 100644 --- a/internal/proxy/director/layer/authn/oidc/authenticator.go +++ b/internal/proxy/director/layer/authn/oidc/authenticator.go @@ -1,11 +1,16 @@ package oidc import ( + "bytes" "context" + "crypto/tls" "fmt" "net/http" "net/url" + "text/template" + "time" + "forge.cadoles.com/Cadoles/go-proxy/wildcard" "forge.cadoles.com/cadoles/bouncer/internal/proxy/director" "forge.cadoles.com/cadoles/bouncer/internal/proxy/director/layer/authn" "forge.cadoles.com/cadoles/bouncer/internal/store" @@ -17,7 +22,9 @@ import ( ) type Authenticator struct { - store sessions.Store + store sessions.Store + httpTransport *http.Transport + httpClientTimeout time.Duration } func (a *Authenticator) PreAuthentication(w http.ResponseWriter, r *http.Request, layer *store.Layer) error { @@ -28,7 +35,9 @@ func (a *Authenticator) PreAuthentication(w http.ResponseWriter, r *http.Request return errors.WithStack(err) } - options, err := fromStoreOptions(layer.Options) + baseURL := originalURL.Scheme + "://" + originalURL.Host + + options, err := fromStoreOptions(layer.Options, baseURL) if err != nil { return errors.WithStack(err) } @@ -38,16 +47,30 @@ func (a *Authenticator) PreAuthentication(w http.ResponseWriter, r *http.Request logger.Error(ctx, "could not retrieve session", logger.E(errors.WithStack(err))) } - redirectURL := a.getRedirectURL(layer.Proxy, layer.Name, originalURL, options) - logoutURL := a.getLogoutURL(layer.Proxy, layer.Name, originalURL, options) - - client, err := a.getClient(options, redirectURL.String()) + loginCallbackURL, err := a.getLoginCallbackURL(layer.Proxy, layer.Name, options) if err != nil { return errors.WithStack(err) } - switch r.URL.Path { - case redirectURL.Path: + client, err := a.getClient(options, loginCallbackURL.String()) + if err != nil { + return errors.WithStack(err) + } + + loginCallbackURLPattern, err := a.templatize(options.OIDC.MatchLoginCallbackURL, layer.Proxy, layer.Name) + if err != nil { + return errors.WithStack(err) + } + + logoutURLPattern, err := a.templatize(options.OIDC.MatchLogoutURL, layer.Proxy, layer.Name) + if err != nil { + return errors.WithStack(err) + } + + logger.Debug(ctx, "checking url", logger.F("loginCallbackURLPattern", loginCallbackURLPattern), logger.F("logoutURLPattern", logoutURLPattern)) + + switch { + case wildcard.Match(originalURL.String(), loginCallbackURLPattern): if err := client.HandleCallback(w, r, sess); err != nil { return errors.WithStack(err) } @@ -57,7 +80,7 @@ func (a *Authenticator) PreAuthentication(w http.ResponseWriter, r *http.Request metricLabelProxy: string(layer.Proxy), }).Add(1) - case logoutURL.Path: + case wildcard.Match(originalURL.String(), logoutURLPattern): postLogoutRedirectURL := options.OIDC.PostLogoutRedirectURL if options.OIDC.PostLogoutRedirectURL == "" { postLogoutRedirectURL = originalURL.Scheme + "://" + originalURL.Host @@ -85,7 +108,9 @@ func (a *Authenticator) Authenticate(w http.ResponseWriter, r *http.Request, lay return nil, errors.WithStack(err) } - options, err := fromStoreOptions(layer.Options) + baseURL := originalURL.Scheme + "://" + originalURL.Host + + options, err := fromStoreOptions(layer.Options, baseURL) if err != nil { return nil, errors.WithStack(err) } @@ -117,9 +142,12 @@ func (a *Authenticator) Authenticate(w http.ResponseWriter, r *http.Request, lay sess.Options.SameSite = http.SameSiteDefaultMode } - redirectURL := a.getRedirectURL(layer.Proxy, layer.Name, originalURL, options) + loginCallbackURL, err := a.getLoginCallbackURL(layer.Proxy, layer.Name, options) + if err != nil { + return nil, errors.WithStack(err) + } - client, err := a.getClient(options, redirectURL.String()) + client, err := a.getClient(options, loginCallbackURL.String()) if err != nil { return nil, errors.WithStack(err) } @@ -138,7 +166,7 @@ func (a *Authenticator) Authenticate(w http.ResponseWriter, r *http.Request, lay return nil, errors.WithStack(err) } - user, err := a.toUser(idToken, layer.Proxy, layer.Name, originalURL, options, sess) + user, err := a.toUser(idToken, layer.Proxy, layer.Name, options, sess) if err != nil { return nil, errors.WithStack(err) } @@ -196,7 +224,7 @@ func (c claims) AsAttrs() map[string]any { return attrs } -func (a *Authenticator) toUser(idToken *oidc.IDToken, proxyName store.ProxyName, layerName store.LayerName, originalURL *url.URL, options *LayerOptions, sess *sessions.Session) (*authn.User, error) { +func (a *Authenticator) toUser(idToken *oidc.IDToken, proxyName store.ProxyName, layerName store.LayerName, options *LayerOptions, sess *sessions.Session) (*authn.User, error) { var claims claims if err := idToken.Claims(&claims); err != nil { @@ -209,7 +237,11 @@ func (a *Authenticator) toUser(idToken *oidc.IDToken, proxyName store.ProxyName, attrs := claims.AsAttrs() - logoutURL := a.getLogoutURL(proxyName, layerName, originalURL, options) + logoutURL, err := a.getLogoutURL(proxyName, layerName, options) + if err != nil { + return nil, errors.WithStack(err) + } + attrs["logout_url"] = logoutURL.String() if accessToken, exists := sess.Values[sessionKeyAccessToken]; exists && accessToken != nil { @@ -229,25 +261,80 @@ func (a *Authenticator) toUser(idToken *oidc.IDToken, proxyName store.ProxyName, return user, nil } -func (a *Authenticator) getRedirectURL(proxyName store.ProxyName, layerName store.LayerName, u *url.URL, options *LayerOptions) *url.URL { - return &url.URL{ - Scheme: u.Scheme, - Host: u.Host, - Path: fmt.Sprintf(options.OIDC.LoginCallbackPath, fmt.Sprintf("%s/%s", proxyName, layerName)), +func (a *Authenticator) getLoginCallbackURL(proxyName store.ProxyName, layerName store.LayerName, options *LayerOptions) (*url.URL, error) { + url, err := a.generateURL(options.OIDC.LoginCallbackURL, proxyName, layerName) + if err != nil { + return nil, errors.WithStack(err) } + + return url, nil } -func (a *Authenticator) getLogoutURL(proxyName store.ProxyName, layerName store.LayerName, u *url.URL, options *LayerOptions) *url.URL { - return &url.URL{ - Scheme: u.Scheme, - Host: u.Host, - Path: fmt.Sprintf(options.OIDC.LogoutPath, fmt.Sprintf("%s/%s", proxyName, layerName)), +func (a *Authenticator) getLogoutURL(proxyName store.ProxyName, layerName store.LayerName, options *LayerOptions) (*url.URL, error) { + url, err := a.generateURL(options.OIDC.LogoutURL, proxyName, layerName) + if err != nil { + return nil, errors.WithStack(err) } + + return url, nil +} + +func (a *Authenticator) generateURL(rawURLTemplate string, proxyName store.ProxyName, layerName store.LayerName) (*url.URL, error) { + rawURL, err := a.templatize(rawURLTemplate, proxyName, layerName) + if err != nil { + return nil, errors.WithStack(err) + } + + url, err := url.Parse(rawURL) + if err != nil { + return nil, errors.WithStack(err) + } + + return url, nil +} + +func (a *Authenticator) templatize(rawTemplate string, proxyName store.ProxyName, layerName store.LayerName) (string, error) { + tmpl, err := template.New("").Parse(rawTemplate) + if err != nil { + return "", errors.WithStack(err) + } + + var raw bytes.Buffer + + err = tmpl.Execute(&raw, struct { + ProxyName store.ProxyName + LayerName store.LayerName + }{ + ProxyName: proxyName, + LayerName: layerName, + }) + if err != nil { + return "", errors.WithStack(err) + } + + return raw.String(), nil } func (a *Authenticator) getClient(options *LayerOptions, redirectURL string) (*Client, error) { ctx := context.Background() + transport := a.httpTransport.Clone() + + if options.OIDC.TLSInsecureSkipVerify { + if transport.TLSClientConfig == nil { + transport.TLSClientConfig = &tls.Config{} + } + + transport.TLSClientConfig.InsecureSkipVerify = true + } + + httpClient := &http.Client{ + Timeout: a.httpClientTimeout, + Transport: transport, + } + + ctx = oidc.ClientContext(ctx, httpClient) + if options.OIDC.SkipIssuerVerification { ctx = oidc.InsecureIssuerURLContext(ctx, options.OIDC.IssuerURL) } @@ -263,6 +350,7 @@ func (a *Authenticator) getClient(options *LayerOptions, redirectURL string) (*C WithRedirectURL(redirectURL), WithScopes(options.OIDC.Scopes...), WithAuthParams(options.OIDC.AuthParams), + WithHTTPClient(httpClient), ) return client, nil diff --git a/internal/proxy/director/layer/authn/oidc/client.go b/internal/proxy/director/layer/authn/oidc/client.go index 417fb97..afa2f56 100644 --- a/internal/proxy/director/layer/authn/oidc/client.go +++ b/internal/proxy/director/layer/authn/oidc/client.go @@ -30,6 +30,7 @@ var ( ) type Client struct { + httpClient *http.Client oauth2 *oauth2.Config provider *oidc.Provider verifier *oidc.IDTokenVerifier @@ -210,6 +211,7 @@ func (c *Client) sessionEndURL(idTokenHint, state, postLogoutRedirectURL string) func (c *Client) validate(r *http.Request, sess *sessions.Session) (*oauth2.Token, *oidc.IDToken, string, error) { ctx := r.Context() + ctx = oidc.ClientContext(ctx, c.httpClient) rawStoredState := sess.Values[sessionKeyLoginState] receivedState := r.URL.Query().Get("state") @@ -287,5 +289,6 @@ func NewClient(funcs ...ClientOptionFunc) *Client { provider: opts.Provider, verifier: verifier, authParams: opts.AuthParams, + httpClient: opts.HTTPClient, } } diff --git a/internal/proxy/director/layer/authn/oidc/client_options.go b/internal/proxy/director/layer/authn/oidc/client_options.go index 2c7b53e..c7608dc 100644 --- a/internal/proxy/director/layer/authn/oidc/client_options.go +++ b/internal/proxy/director/layer/authn/oidc/client_options.go @@ -2,6 +2,7 @@ package oidc import ( "context" + "net/http" "github.com/coreos/go-oidc/v3/oidc" ) @@ -14,6 +15,7 @@ type ClientOptions struct { Scopes []string AuthParams map[string]string SkipIssuerCheck bool + HTTPClient *http.Client } type ClientOptionFunc func(*ClientOptions) @@ -63,9 +65,16 @@ func WithProvider(provider *oidc.Provider) ClientOptionFunc { } } +func WithHTTPClient(client *http.Client) ClientOptionFunc { + return func(opt *ClientOptions) { + opt.HTTPClient = client + } +} + func NewClientOptions(funcs ...ClientOptionFunc) *ClientOptions { opt := &ClientOptions{ - Scopes: []string{oidc.ScopeOpenID, "profile"}, + Scopes: []string{oidc.ScopeOpenID, "profile"}, + HTTPClient: http.DefaultClient, } for _, f := range funcs { diff --git a/internal/proxy/director/layer/authn/oidc/layer-options.json b/internal/proxy/director/layer/authn/oidc/layer-options.json index e11e935..6749fb3 100644 --- a/internal/proxy/director/layer/authn/oidc/layer-options.json +++ b/internal/proxy/director/layer/authn/oidc/layer-options.json @@ -42,22 +42,39 @@ } } }, - "loginCallbackPath": { + "loginCallbackURL": { "title": "Chemin associé à l'URL de callback OpenID Connect", - "default": "/.bouncer/authn/oidc/%s/callback", - "description": "Le marqueur '%s' peut être utilisé pour injecter l'espace de nom '/'.", + "default": ":///.bouncer/authn/oidc/{{ .ProxyName }}/{{ .LayerName }}/callback", + "description": "Les marqueurs '{{ .ProxyName }}' et '{{ .LayerName }}' peuvent être utilisés pour injecter le nom du proxy ainsi que celui du layer.", "type": "string" }, - "logoutPath": { + "matchLoginCallbackURL": { + "title": "Patron de correspondance de l'URL interne de callback OpenID Connect", + "default": "*/.bouncer/authn/oidc/{{ .ProxyName }}/{{ .LayerName }}/callback", + "description": "Les marqueurs '{{ .ProxyName }}' et '{{ .LayerName }}' peuvent être utilisés pour injecter le nom du proxy ainsi que celui du layer.", + "type": "string" + }, + "logoutURL": { "title": "Chemin associé à l'URL de déconnexion", - "default": "/.bouncer/authn/oidc/%s/logout", - "description": "Le marqueur '%s' peut être utilisé pour injecter l'espace de nom '/'.", + "default": ":///.bouncer/authn/oidc/{{ .ProxyName }}/{{ .LayerName }}/logout", + "description": "Les marqueurs '{{ .ProxyName }}' et '{{ .LayerName }}' peuvent être utilisés pour injecter le nom du proxy ainsi que celui du layer.", + "type": "string" + }, + "matchLogoutURL": { + "title": "Patron de correspondance l'URL interne de déconnexion", + "default": "*/.bouncer/authn/oidc/{{ .ProxyName }}/{{ .LayerName }}/logout", + "description": "Les marqueurs '{{ .ProxyName }}' et '{{ .LayerName }}' peuvent être utilisés pour injecter le nom du proxy ainsi que celui du layer.", "type": "string" }, "skipIssuerVerification": { "title": "Activer/désactiver la vérification de concordance de l'identifiant du fournisseur d'identité", "default": false, "type": "boolean" + }, + "tlsInsecureSkipVerify": { + "title": "Activer/désactiver la vérification du certificat TLS distant", + "default": false, + "type": "boolean" } }, "additionalProperties": false, diff --git a/internal/proxy/director/layer/authn/oidc/layer.go b/internal/proxy/director/layer/authn/oidc/layer.go index 4a0d87c..2c242b2 100644 --- a/internal/proxy/director/layer/authn/oidc/layer.go +++ b/internal/proxy/director/layer/authn/oidc/layer.go @@ -8,6 +8,11 @@ import ( const LayerType store.LayerType = "authn-oidc" -func NewLayer(store sessions.Store) *authn.Layer { - return authn.NewLayer(LayerType, &Authenticator{store: store}) +func NewLayer(store sessions.Store, funcs ...OptionFunc) *authn.Layer { + opts := NewOptions(funcs...) + return authn.NewLayer(LayerType, &Authenticator{ + httpTransport: opts.HTTPTransport, + httpClientTimeout: opts.HTTPClientTimeout, + store: store, + }) } diff --git a/internal/proxy/director/layer/authn/oidc/layer_options.go b/internal/proxy/director/layer/authn/oidc/layer_options.go index 4317840..873975d 100644 --- a/internal/proxy/director/layer/authn/oidc/layer_options.go +++ b/internal/proxy/director/layer/authn/oidc/layer_options.go @@ -19,11 +19,14 @@ type LayerOptions struct { type OIDCOptions struct { ClientID string `mapstructure:"clientId"` ClientSecret string `mapstructure:"clientSecret"` - LoginCallbackPath string `mapstructure:"loginCallbackPath"` - LogoutPath string `mapstructure:"logoutPath"` + LoginCallbackURL string `mapstructure:"loginCallbackURL"` + MatchLoginCallbackURL string `mapstructure:"matchLoginCallbackURL"` + LogoutURL string `mapstructure:"logoutURL"` + MatchLogoutURL string `mapstructure:"matchLogoutURL"` IssuerURL string `mapstructure:"issuerURL"` SkipIssuerVerification bool `mapstructure:"skipIssuerVerification"` PostLogoutRedirectURL string `mapstructure:"postLogoutRedirectURL"` + TLSInsecureSkipVerify bool `mapstructure:"tlsInsecureSkipVerify"` Scopes []string `mapstructure:"scopes"` AuthParams map[string]string `mapstructure:"authParams"` } @@ -38,13 +41,18 @@ type CookieOptions struct { MaxAge time.Duration `mapstructure:"maxAge"` } -func fromStoreOptions(storeOptions store.LayerOptions) (*LayerOptions, error) { +func fromStoreOptions(storeOptions store.LayerOptions, baseURL string) (*LayerOptions, error) { + loginCallbackPath := "/.bouncer/authn/oidc/{{ .ProxyName }}/{{ .LayerName }}/callback" + logoutPath := "/.bouncer/authn/oidc/{{ .ProxyName }}/{{ .LayerName }}/logout" + layerOptions := LayerOptions{ LayerOptions: authn.DefaultLayerOptions(), OIDC: OIDCOptions{ - LoginCallbackPath: "/.bouncer/authn/oidc/%s/callback", - LogoutPath: "/.bouncer/authn/oidc/%s/logout", - Scopes: []string{"openid"}, + LoginCallbackURL: baseURL + loginCallbackPath, + MatchLoginCallbackURL: "*" + loginCallbackPath, + LogoutURL: baseURL + logoutPath, + MatchLogoutURL: "*" + logoutPath, + Scopes: []string{"openid"}, }, Cookie: CookieOptions{ Name: defaultCookieName, diff --git a/internal/proxy/director/layer/authn/oidc/options.go b/internal/proxy/director/layer/authn/oidc/options.go new file mode 100644 index 0000000..9ce69e1 --- /dev/null +++ b/internal/proxy/director/layer/authn/oidc/options.go @@ -0,0 +1,38 @@ +package oidc + +import ( + "net/http" + "time" +) + +type Options struct { + HTTPTransport *http.Transport + HTTPClientTimeout time.Duration +} + +type OptionFunc func(opts *Options) + +func WithHTTPTransport(transport *http.Transport) OptionFunc { + return func(opts *Options) { + opts.HTTPTransport = transport + } +} + +func WithHTTPClientTimeout(timeout time.Duration) OptionFunc { + return func(opts *Options) { + opts.HTTPClientTimeout = timeout + } +} + +func NewOptions(funcs ...OptionFunc) *Options { + opts := &Options{ + HTTPTransport: http.DefaultTransport.(*http.Transport), + HTTPClientTimeout: 30 * time.Second, + } + + for _, fn := range funcs { + fn(opts) + } + + return opts +} diff --git a/internal/proxy/server.go b/internal/proxy/server.go index 47f4d8c..8cd7f21 100644 --- a/internal/proxy/server.go +++ b/internal/proxy/server.go @@ -159,26 +159,10 @@ func (s *Server) createReverseProxy(ctx context.Context, target *url.URL) *httpu DualStack: bool(dialConfig.DualStack), } - transportConfig := s.serverConfig.Transport - - reverseProxy.Transport = &http.Transport{ - Proxy: http.ProxyFromEnvironment, - DialContext: dialer.DialContext, - ForceAttemptHTTP2: bool(transportConfig.ForceAttemptHTTP2), - MaxIdleConns: int(transportConfig.MaxIdleConns), - MaxIdleConnsPerHost: int(transportConfig.MaxIdleConnsPerHost), - MaxConnsPerHost: int(transportConfig.MaxConnsPerHost), - IdleConnTimeout: time.Duration(*transportConfig.IdleConnTimeout), - TLSHandshakeTimeout: time.Duration(*transportConfig.TLSHandshakeTimeout), - ExpectContinueTimeout: time.Duration(*transportConfig.ExpectContinueTimeout), - DisableKeepAlives: bool(transportConfig.DisableKeepAlives), - DisableCompression: bool(transportConfig.DisableCompression), - ResponseHeaderTimeout: time.Duration(*transportConfig.ResponseHeaderTimeout), - WriteBufferSize: int(transportConfig.WriteBufferSize), - ReadBufferSize: int(transportConfig.ReadBufferSize), - MaxResponseHeaderBytes: int64(transportConfig.MaxResponseHeaderBytes), - } + httpTransport := s.serverConfig.Transport.AsTransport() + httpTransport.DialContext = dialer.DialContext + reverseProxy.Transport = httpTransport reverseProxy.ErrorHandler = s.errorHandler return reverseProxy diff --git a/internal/setup/authn_oidc_layer.go b/internal/setup/authn_oidc_layer.go index 41ca45e..be2cf6b 100644 --- a/internal/setup/authn_oidc_layer.go +++ b/internal/setup/authn_oidc_layer.go @@ -1,6 +1,8 @@ package setup import ( + "time" + "forge.cadoles.com/cadoles/bouncer/internal/config" "forge.cadoles.com/cadoles/bouncer/internal/proxy/director" "forge.cadoles.com/cadoles/bouncer/internal/proxy/director/layer/authn" @@ -25,5 +27,11 @@ func setupAuthnOIDCLayer(conf *config.Config) (director.Layer, error) { adapter := redis.NewStoreAdapter(rdb) store := session.NewStore(adapter) - return oidc.NewLayer(store), nil + transport := conf.Layers.Authn.OIDC.HTTPClient.AsTransport() + + return oidc.NewLayer( + store, + oidc.WithHTTPTransport(transport), + oidc.WithHTTPClientTimeout(time.Duration(*conf.Layers.Authn.OIDC.HTTPClient.Timeout)), + ), nil }