Skip to content
This repository has been archived by the owner on Dec 7, 2020. It is now read-only.

Commit

Permalink
- adding the skip-client-id check option, to skip verification of the…
Browse files Browse the repository at this point in the history
… audience claim in the token
  • Loading branch information
gambol99 committed Jun 11, 2017
1 parent 0f4f114 commit 0a7ec08
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 9 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ NAME=keycloak-proxy
AUTHOR=gambol99
AUTHOR_EMAIL[email protected]
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)
Expand Down
2 changes: 2 additions & 0 deletions doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)"`
Expand Down
3 changes: 2 additions & 1 deletion middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions middleware_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down
64 changes: 64 additions & 0 deletions server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
15 changes: 8 additions & 7 deletions utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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")
Expand All @@ -192,9 +192,10 @@ func newOpenIDClient(cfg *Config) (*oidc.Client, oidc.ProviderConfig, *http.Clie
ID: cfg.ClientID,
Secret: cfg.ClientSecret,
},
RedirectURL: fmt.Sprintf("%s/oauth/callback", cfg.RedirectionURL),
Scope: append(cfg.Scopes, oidc.DefaultScope...),
HTTPClient: hc,
RedirectURL: fmt.Sprintf("%s/oauth/callback", cfg.RedirectionURL),
Scope: append(cfg.Scopes, oidc.DefaultScope...),
SkipClientIDCheck: cfg.SkipClientID,
HTTPClient: hc,
})
if err != nil {
return nil, config, hc, err
Expand Down

0 comments on commit 0a7ec08

Please sign in to comment.