Skip to content
Snippets Groups Projects
Commit 0a7ec080 authored by Rohith's avatar Rohith
Browse files

- adding the skip-client-id check option, to skip verification of the audience claim in the token

parent 0f4f114f
Branches
Tags
No related merge requests found
......@@ -2,7 +2,7 @@ NAME=keycloak-proxy
AUTHOR=gambol99
AUTHOR_EMAIL=gambol99@gmail.com
REGISTRY=quay.io
GOVERSION ?= 1.8.1
GOVERSION ?= 1.8.3
ROOT_DIR=${PWD}
HARDWARE=$(shell uname -m)
GIT_SHA=$(shell git --no-pager describe --always --dirty)
......
......@@ -184,6 +184,8 @@ type Config struct {
TLSClientCertificate string `json:"tls-client-certificate" yaml:"tls-client-certificate" usage:"path to the client certificate for outbound connections in reverse and forwarding proxy modes"`
// SkipUpstreamTLSVerify skips the verification of any upstream tls
SkipUpstreamTLSVerify bool `json:"skip-upstream-tls-verify" yaml:"skip-upstream-tls-verify" usage:"skip the verification of any upstream TLS"`
// SkipClientID indicates we don't need to check the client id of the token
SkipClientID bool `json:"skip-client-id" yaml:"skip-client-id" usage:"skip the check on the client token"`
// CorsOrigins is a list of origins permitted
CorsOrigins []string `json:"cors-origins" yaml:"cors-origins" usage:"origins to add to the CORE origins control (Access-Control-Allow-Origin)"`
......
......@@ -101,7 +101,7 @@ func (r *oauthProxy) metricsMiddleware() echo.MiddlewareFunc {
},
[]string{"code", "method"},
)
prometheus.MustRegisterOrGet(statusMetrics)
prometheus.MustRegister(statusMetrics)
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(cx echo.Context) error {
......@@ -303,6 +303,7 @@ func (r *oauthProxy) admissionMiddleware(resource *Resource) echo.MiddlewareFunc
log.WithFields(log.Fields{
"access": "permitted",
"client": user.audience,
"email": user.email,
"expires": time.Until(user.expiresAt).String(),
"resource": resource.URL,
......
......@@ -78,6 +78,7 @@ func newFakeProxy(c *Config) *fakeProxy {
auth := newFakeAuthServer()
c.DiscoveryURL = auth.getLocation()
c.RevocationEndpoint = auth.getRevocationURL()
c.Verbose = false
proxy, err := newProxy(c)
if err != nil {
panic("failed to create fake proxy service, error: " + err.Error())
......
......@@ -226,6 +226,70 @@ func TestTokenEncryption(t *testing.T) {
newFakeProxy(c).RunTests(t, requests)
}
func TestSkipClientIDDisabled(t *testing.T) {
c := newFakeKeycloakConfig()
p := newFakeProxy(c)
// create two token, one with a bad client id
bad := newTestToken(p.idp.getLocation())
bad.merge(jose.Claims{"aud": "bad_client_id"})
badSigned, _ := p.idp.signToken(bad.claims)
// and the good
good := newTestToken(p.idp.getLocation())
goodSigned, _ := p.idp.signToken(good.claims)
requests := []fakeRequest{
{
URI: "/auth_all/test",
RawToken: goodSigned.Encode(),
ExpectedProxy: true,
ExpectedCode: http.StatusOK,
},
{
URI: "/auth_all/test",
RawToken: badSigned.Encode(),
ExpectedCode: http.StatusForbidden,
},
}
p.RunTests(t, requests)
}
func TestSkipClientIDEnabled(t *testing.T) {
c := newFakeKeycloakConfig()
c.SkipClientID = true
p := newFakeProxy(c)
// create two token, one with a bad client id
bad := newTestToken(p.idp.getLocation())
bad.merge(jose.Claims{"aud": "bad_client_id"})
badSigned, _ := p.idp.signToken(bad.claims)
// and the good
good := newTestToken(p.idp.getLocation())
goodSigned, _ := p.idp.signToken(good.claims)
// bad issuer
badIssurer := newTestToken("http://someone_else")
badIssurer.merge(jose.Claims{"aud": "bad_client_id"})
badIssuerSigned, _ := p.idp.signToken(badIssurer.claims)
requests := []fakeRequest{
{
URI: "/auth_all/test",
RawToken: goodSigned.Encode(),
ExpectedProxy: true,
ExpectedCode: http.StatusOK,
},
{
URI: "/auth_all/test",
RawToken: badSigned.Encode(),
ExpectedProxy: true,
ExpectedCode: http.StatusOK,
},
{
URI: "/auth_all/test",
RawToken: badIssuerSigned.Encode(),
ExpectedCode: http.StatusForbidden,
},
}
p.RunTests(t, requests)
}
func newTestService() string {
_, _, u := newTestProxyService(nil)
return u
......
......@@ -150,22 +150,22 @@ func newOpenIDClient(cfg *Config) (*oidc.Client, oidc.ProviderConfig, *http.Clie
var err error
var config oidc.ProviderConfig
// step: fix up the url if required, the underlining lib will add the .well-known/openid-configuration to the discovery url for us.
// fix up the url if required, the underlining lib will add the .well-known/openid-configuration to the discovery url for us.
if strings.HasSuffix(cfg.DiscoveryURL, "/.well-known/openid-configuration") {
cfg.DiscoveryURL = strings.TrimSuffix(cfg.DiscoveryURL, "/.well-known/openid-configuration")
}
// step: create a idp http client
hc := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: cfg.SkipOpenIDProviderTLSVerify,
},
IdleConnTimeout: time.Second * 10,
},
Timeout: time.Second * 10,
}
// step: attempt to retrieve the provider configuration
// attempt to retrieve the provider configuration
completeCh := make(chan bool)
go func() {
for {
......@@ -178,7 +178,7 @@ func newOpenIDClient(cfg *Config) (*oidc.Client, oidc.ProviderConfig, *http.Clie
}
completeCh <- true
}()
// step: wait for timeout or successful retrieval
// wait for timeout or successful retrieval
select {
case <-time.After(30 * time.Second):
return nil, config, nil, errors.New("failed to retrieve the provider configuration from discovery url")
......@@ -194,6 +194,7 @@ func newOpenIDClient(cfg *Config) (*oidc.Client, oidc.ProviderConfig, *http.Clie
},
RedirectURL: fmt.Sprintf("%s/oauth/callback", cfg.RedirectionURL),
Scope: append(cfg.Scopes, oidc.DefaultScope...),
SkipClientIDCheck: cfg.SkipClientID,
HTTPClient: hc,
})
if err != nil {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment