Skip to content

Commit 2b96742

Browse files
committed
feat: back-channel logout request client tls configuration
1 parent 8da9e01 commit 2b96742

File tree

6 files changed

+298
-9
lines changed

6 files changed

+298
-9
lines changed

consent/strategy_default.go

+19-5
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ package consent
2222

2323
import (
2424
"context"
25+
"github.com/ory/x/httpx"
2526
"net/http"
2627
"net/url"
2728
"strconv"
@@ -60,17 +61,30 @@ const (
6061
)
6162

6263
type DefaultStrategy struct {
63-
c *config.DefaultProvider
64-
r InternalRegistry
64+
c *config.DefaultProvider
65+
r InternalRegistry
66+
httpClientOptions httpx.ResilientOptions
6567
}
6668

6769
func NewStrategy(
6870
r InternalRegistry,
6971
c *config.DefaultProvider,
7072
) *DefaultStrategy {
73+
httpClientTlsConfig, err := c.TLSClientConfigWithDefaultFallback(config.KeyPrefixClientBackChannelLogout)
74+
if err != nil {
75+
r.Logger().WithError(err).Fatalf("Unable to setup back-channel logout http client TLS configuration.")
76+
}
77+
httpClientOptions := httpx.ResilientClientWithClient(&http.Client{
78+
Timeout: time.Minute,
79+
Transport: &http.Transport{
80+
Proxy: http.ProxyFromEnvironment,
81+
TLSClientConfig: httpClientTlsConfig,
82+
},
83+
})
7184
return &DefaultStrategy{
72-
c: c,
73-
r: r,
85+
c: c,
86+
r: r,
87+
httpClientOptions: httpClientOptions,
7488
}
7589
}
7690

@@ -674,7 +688,7 @@ func (s *DefaultStrategy) executeBackChannelLogout(ctx context.Context, r *http.
674688
WithField("client_id", t.clientID).
675689
WithField("backchannel_logout_url", t.url)
676690

677-
res, err := s.r.HTTPClient(ctx).PostForm(t.url, url.Values{"logout_token": {t.token}})
691+
res, err := s.r.HTTPClient(ctx, s.httpClientOptions).PostForm(t.url, url.Values{"logout_token": {t.token}})
678692
if err != nil {
679693
log.WithError(err).Error("Unable to execute OpenID Connect Back-Channel Logout Request")
680694
return

driver/config/tls.go

+72
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ package config
33
import (
44
"context"
55
"crypto/tls"
6+
"fmt"
7+
"strings"
8+
9+
"github.com/hashicorp/go-secure-stdlib/tlsutil"
10+
"github.com/pkg/errors"
611

712
"github.com/ory/x/tlsx"
813
)
@@ -21,6 +26,35 @@ const (
2126
KeyTLSCertPath = "serve." + KeySuffixTLSCertPath
2227
KeyTLSKeyPath = "serve." + KeySuffixTLSKeyPath
2328
KeyTLSEnabled = "serve." + KeySuffixTLSEnabled
29+
30+
KeyClientTLSInsecureSkipVerify = "tls.insecure_skip_verify"
31+
KeySuffixClientTLSCipherSuites = "tls.cipher_suites"
32+
KeySuffixClientTLSMinVer = "tls.min_version"
33+
KeySuffixClientTLSMaxVer = "tls.max_version"
34+
)
35+
36+
type ClientInterface interface {
37+
Key(suffix string) string
38+
}
39+
40+
func (iface *clientPrefix) Key(suffix string) string {
41+
return fmt.Sprintf("%s.%s", iface.prefix, suffix)
42+
}
43+
44+
type clientPrefix struct {
45+
prefix string
46+
}
47+
48+
var (
49+
KeyPrefixClientDefault ClientInterface = &clientPrefix{
50+
prefix: "client.default",
51+
}
52+
KeyPrefixClientBackChannelLogout ClientInterface = &clientPrefix{
53+
prefix: "client.back_channel_logout",
54+
}
55+
KeyPrefixClientRefreshTokenHook ClientInterface = &clientPrefix{
56+
prefix: "client.refresh_token_hook",
57+
}
2458
)
2559

2660
type TLSConfig interface {
@@ -58,6 +92,44 @@ func (p *DefaultProvider) TLS(ctx context.Context, iface ServeInterface) TLSConf
5892
}
5993
}
6094

95+
func (p *DefaultProvider) TLSClientConfigDefault() (*tls.Config, error) {
96+
return p.TLSClientConfigWithDefaultFallback(KeyPrefixClientDefault)
97+
}
98+
99+
func (p *DefaultProvider) TLSClientConfigWithDefaultFallback(iface ClientInterface) (*tls.Config, error) {
100+
tlsClientConfig := new(tls.Config)
101+
tlsClientConfig.InsecureSkipVerify = p.p.BoolF(KeyClientTLSInsecureSkipVerify, false)
102+
103+
if p.p.Exists(KeyPrefixClientDefault.Key(KeySuffixClientTLSCipherSuites)) || p.p.Exists(iface.Key(KeySuffixClientTLSCipherSuites)) {
104+
keyCipherSuites := p.p.StringsF(iface.Key(KeySuffixClientTLSCipherSuites), p.p.Strings(KeyPrefixClientDefault.Key(KeySuffixClientTLSCipherSuites)))
105+
cipherSuites, err := tlsutil.ParseCiphers(strings.Join(keyCipherSuites[:], ","))
106+
if err != nil {
107+
return nil, errors.WithMessage(err, "Unable to setup client TLS configuration")
108+
}
109+
tlsClientConfig.CipherSuites = cipherSuites
110+
}
111+
112+
if p.p.Exists(KeyPrefixClientDefault.Key(KeySuffixClientTLSMinVer)) || p.p.Exists(iface.Key(KeySuffixClientTLSMinVer)) {
113+
keyMinVer := p.p.StringF(iface.Key(KeySuffixClientTLSMinVer), p.p.String(KeyPrefixClientDefault.Key(KeySuffixClientTLSMinVer)))
114+
if tlsMinVer, found := tlsutil.TLSLookup[keyMinVer]; !found {
115+
return nil, errors.Errorf("Unable to setup client TLS configuration. Invalid minimum TLS version: %s", keyMinVer)
116+
} else {
117+
tlsClientConfig.MinVersion = tlsMinVer
118+
}
119+
}
120+
121+
if p.p.Exists(KeyPrefixClientDefault.Key(KeySuffixClientTLSMaxVer)) || p.p.Exists(iface.Key(KeySuffixClientTLSMaxVer)) {
122+
keyMaxVer := p.p.StringF(iface.Key(KeySuffixClientTLSMaxVer), p.p.String(KeyPrefixClientDefault.Key(KeySuffixClientTLSMaxVer)))
123+
if tlsMaxVer, found := tlsutil.TLSLookup[keyMaxVer]; !found {
124+
return nil, errors.Errorf("Unable to setup client TLS configuration. Invalid maximum TLS version: %s", keyMaxVer)
125+
} else {
126+
tlsClientConfig.MaxVersion = tlsMaxVer
127+
}
128+
}
129+
130+
return tlsClientConfig, nil
131+
}
132+
61133
func (c *tlsConfig) Certificate() ([]tls.Certificate, error) {
62134
return tlsx.Certificate(c.certString, c.keyString, c.certPath, c.keyPath)
63135
}

driver/config/tls_test.go

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package config
2+
3+
import (
4+
"context"
5+
"crypto/tls"
6+
"testing"
7+
8+
"github.com/stretchr/testify/assert"
9+
10+
"github.com/ory/x/configx"
11+
"github.com/ory/x/logrusx"
12+
)
13+
14+
func TestTLSClientConfig_CipherSuite(t *testing.T) {
15+
l := logrusx.New("", "")
16+
c := MustNew(context.TODO(), l, configx.WithValue("client.default.tls.cipher_suites", []string{"TLS_AES_128_GCM_SHA256", "TLS_AES_256_GCM_SHA384"}))
17+
18+
tlsClientConfig, err := c.TLSClientConfigDefault()
19+
assert.NoError(t, err)
20+
cipherSuites := tlsClientConfig.CipherSuites
21+
22+
assert.Len(t, cipherSuites, 2)
23+
assert.Equal(t, tls.TLS_AES_128_GCM_SHA256, cipherSuites[0])
24+
assert.Equal(t, tls.TLS_AES_256_GCM_SHA384, cipherSuites[1])
25+
}
26+
27+
func TestTLSClientConfig_InvalidCipherSuite(t *testing.T) {
28+
l := logrusx.New("", "")
29+
c := MustNew(context.TODO(), l, configx.WithValue("client.default.tls.cipher_suites", []string{"TLS_AES_128_GCM_SHA256", "TLS_INVALID_CIPHER_SUITE"}))
30+
31+
_, err := c.TLSClientConfigDefault()
32+
33+
assert.EqualError(t, err, "Unable to setup client TLS configuration: unsupported cipher \"TLS_INVALID_CIPHER_SUITE\"")
34+
}
35+
36+
func TestTLSClientConfig_MinVersion(t *testing.T) {
37+
l := logrusx.New("", "")
38+
c := MustNew(context.TODO(), l, configx.WithValue("client.default.tls.min_version", "tls13"))
39+
40+
tlsClientConfig, err := c.TLSClientConfigDefault()
41+
42+
assert.NoError(t, err)
43+
assert.Equal(t, uint16(tls.VersionTLS13), tlsClientConfig.MinVersion)
44+
}
45+
46+
func TestTLSClientConfig_InvalidMinVersion(t *testing.T) {
47+
l := logrusx.New("", "")
48+
c := MustNew(context.TODO(), l, configx.WithValue("client.default.tls.min_version", "tlsx"))
49+
50+
_, err := c.TLSClientConfigDefault()
51+
52+
assert.EqualError(t, err, "Unable to setup client TLS configuration. Invalid minimum TLS version: tlsx")
53+
}
54+
55+
func TestTLSClientConfig_MaxVersion(t *testing.T) {
56+
l := logrusx.New("", "")
57+
c := MustNew(context.TODO(), l, configx.WithValue("client.default.tls.max_version", "tls10"))
58+
59+
tlsClientConfig, err := c.TLSClientConfigDefault()
60+
61+
assert.NoError(t, err)
62+
assert.Equal(t, uint16(tls.VersionTLS10), tlsClientConfig.MaxVersion)
63+
}
64+
65+
func TestTLSClientConfig_InvalidMaxTlsVersion(t *testing.T) {
66+
l := logrusx.New("", "")
67+
c := MustNew(context.TODO(), l, configx.WithValue("client.default.tls.max_version", "tlsx"))
68+
69+
_, err := c.TLSClientConfigDefault()
70+
71+
assert.EqualError(t, err, "Unable to setup client TLS configuration. Invalid maximum TLS version: tlsx")
72+
}
73+
74+
func TestTLSClientConfig_WithDefaultFallback(t *testing.T) {
75+
l := logrusx.New("", "")
76+
c := MustNew(context.TODO(), l)
77+
ctx := context.Background()
78+
c.MustSet(ctx, "client.default.tls.min_version", "tls11")
79+
c.MustSet(ctx, "client.default.tls.max_version", "tls12")
80+
c.MustSet(ctx, "client.back_channel_logout.tls.max_version", "tls13")
81+
82+
tlsClientConfig, err := c.TLSClientConfigWithDefaultFallback(KeyPrefixClientBackChannelLogout)
83+
84+
assert.NoError(t, err)
85+
assert.Equal(t, uint16(tls.VersionTLS11), tlsClientConfig.MinVersion)
86+
assert.Equal(t, uint16(tls.VersionTLS13), tlsClientConfig.MaxVersion)
87+
}

go.mod

+5
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ require (
3131
github.com/gorilla/sessions v1.2.1
3232
github.com/gtank/cryptopasta v0.0.0-20170601214702-1f550f6f2f69
3333
github.com/hashicorp/go-retryablehttp v0.7.1
34+
github.com/hashicorp/go-secure-stdlib/tlsutil v0.1.1
3435
github.com/instana/testify v1.6.2-0.20200721153833-94b1851f4d65
3536
github.com/jackc/pgx/v4 v4.16.1
3637
github.com/jmoiron/sqlx v1.3.5
@@ -147,6 +148,9 @@ require (
147148
github.com/gorilla/handlers v1.5.1 // indirect
148149
github.com/gorilla/websocket v1.5.0 // indirect
149150
github.com/grpc-ecosystem/grpc-gateway/v2 v2.10.2 // indirect
151+
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1 // indirect
152+
github.com/hashicorp/go-secure-stdlib/strutil v0.1.1 // indirect
153+
github.com/hashicorp/go-sockaddr v1.0.2 // indirect
150154
github.com/hashicorp/hcl v1.0.0 // indirect
151155
github.com/huandu/xstrings v1.3.2 // indirect
152156
github.com/imdario/mergo v0.3.12 // indirect
@@ -206,6 +210,7 @@ require (
206210
github.com/prometheus/common v0.32.1 // indirect
207211
github.com/prometheus/procfs v0.6.0 // indirect
208212
github.com/rogpeppe/go-internal v1.9.0 // indirect
213+
github.com/ryanuber/go-glob v1.0.0 // indirect
209214
github.com/santhosh-tekuri/jsonschema v1.2.4 // indirect
210215
github.com/seatgeek/logrus-gelf-formatter v0.0.0-20210414080842-5b05eb8ff761 // indirect
211216
github.com/segmentio/backo-go v0.0.0-20200129164019-23eae7c10bd3 // indirect

go.sum

+8
Original file line numberDiff line numberDiff line change
@@ -827,8 +827,15 @@ github.com/hashicorp/go-retryablehttp v0.7.1 h1:sUiuQAnLlbvmExtFQs72iFW/HXeUn8Z1
827827
github.com/hashicorp/go-retryablehttp v0.7.1/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
828828
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
829829
github.com/hashicorp/go-rootcerts v1.0.1/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
830+
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1 h1:78ki3QBevHwYrVxnyVeaEz+7WtifHhauYF23es/0KlI=
831+
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8=
832+
github.com/hashicorp/go-secure-stdlib/strutil v0.1.1 h1:nd0HIW15E6FG1MsnArYaHfuw9C2zgzM8LxkG5Ty/788=
833+
github.com/hashicorp/go-secure-stdlib/strutil v0.1.1/go.mod h1:gKOamz3EwoIoJq7mlMIRBpVTAUn8qPCrEclOKKWhD3U=
834+
github.com/hashicorp/go-secure-stdlib/tlsutil v0.1.1 h1:Yc026VyMyIpq1UWRnakHRG01U8fJm+nEfEmjoAb00n8=
835+
github.com/hashicorp/go-secure-stdlib/tlsutil v0.1.1/go.mod h1:l8slYwnJA26yBz+ErHpp2IRCLr0vuOMGBORIz4rRiAs=
830836
github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
831837
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
838+
github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc=
832839
github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A=
833840
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
834841
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
@@ -1376,6 +1383,7 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD
13761383
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
13771384
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
13781385
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
1386+
github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk=
13791387
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
13801388
github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4=
13811389
github.com/santhosh-tekuri/jsonschema v1.2.4 h1:hNhW8e7t+H1vgY+1QeEQpveR6D4+OwKPXCfD2aieJis=

0 commit comments

Comments
 (0)