From 0398b049a63eb3616990def54225b4f570381ab3 Mon Sep 17 00:00:00 2001 From: Moritz Kammerer Date: Mon, 20 Jan 2020 16:30:05 +0100 Subject: [PATCH] KEYCLOAK-12731 Add option 'UseAuthorizationHeader' to disable reading token from Authorization header This makes it possible to protect applications with the gatekeeper which use the Authorization header with their own JWT token. Default of this value is true (backward compatible). --- config.go | 1 + doc.go | 3 +++ go.mod | 2 ++ session.go | 35 +++++++++++++++++++++++------------ session_test.go | 4 +++- 5 files changed, 32 insertions(+), 13 deletions(-) diff --git a/config.go b/config.go index 080af6ad3..28d4d9b49 100644 --- a/config.go +++ b/config.go @@ -38,6 +38,7 @@ func newDefaultConfig() *Config { ClientAuthMethod: authMethodBasic, CookieAccessName: accessCookie, CookieRefreshName: refreshCookie, + UseAuthorizationHeader: true, EnableAuthorizationCookies: true, EnableAuthorizationHeader: true, EnableDefaultDeny: true, diff --git a/doc.go b/doc.go index b5cf9e5be..575fbb619 100644 --- a/doc.go +++ b/doc.go @@ -197,6 +197,9 @@ type Config struct { // ResponseHeader is a map of response headers to add to the response ResponseHeaders map[string]string `json:"response-headers" yaml:"response-headers" usage:"custom headers to added to the http response key=value"` + // UseAuthorizationHeader indicates if we should read the token from the Authorization header + UseAuthorizationHeader bool `json:"use-authorization-header" yaml:"use-authorization-header" usage:"indicates if we should read token from Authorization header" env:"USE_AUTHORIZATION_HEADER"` + // EnableSelfSignedTLS indicates we should create a self-signed ceritificate for the service EnabledSelfSignedTLS bool `json:"enable-self-signed-tls" yaml:"enable-self-signed-tls" usage:"create self signed certificates for the proxy" env:"ENABLE_SELF_SIGNED_TLS"` // SelfSignedTLSHostnames is the list of hostnames to place on the certificate diff --git a/go.mod b/go.mod index 6ac8067a5..5ee3c4344 100644 --- a/go.mod +++ b/go.mod @@ -35,3 +35,5 @@ require ( gopkg.in/resty.v1 v1.10.3 gopkg.in/yaml.v2 v2.2.2 ) + +go 1.13 diff --git a/session.go b/session.go index d58ce67b9..b862fe1bd 100644 --- a/session.go +++ b/session.go @@ -29,7 +29,7 @@ import ( func (r *oauthProxy) getIdentity(req *http.Request) (*userContext, error) { var isBearer bool // step: check for a bearer token or cookie with jwt token - access, isBearer, err := getTokenInRequest(req, r.config.CookieAccessName) + access, isBearer, err := getTokenInRequest(req, r.config.CookieAccessName, r.config.UseAuthorizationHeader) if err != nil { return nil, err } @@ -69,21 +69,32 @@ func (r *oauthProxy) getRefreshTokenFromCookie(req *http.Request) (string, error } // getTokenInRequest returns the access token from the http request -func getTokenInRequest(req *http.Request, name string) (string, bool, error) { - bearer := true - // step: check for a token in the authorization header - token, err := getTokenInBearer(req) - if err != nil { - if err != ErrSessionNotFound { - return "", false, err +func getTokenInRequest(req *http.Request, name string, useAuthorizationHeader bool) (string, bool, error) { + if useAuthorizationHeader { + // step: check for a token in the authorization header + bearer := true + token, err := getTokenInBearer(req) + + if err != nil { + bearer = false + + if err != ErrSessionNotFound { + return "", bearer, err + } + + if token, err = getTokenInCookie(req, name); err != nil { + return token, bearer, err + } } - if token, err = getTokenInCookie(req, name); err != nil { + return token, bearer, nil + } else { + // step: check for a token in cookie + token, err := getTokenInCookie(req, name) + if err != nil { return token, false, err } - bearer = false + return token, false, nil } - - return token, bearer, nil } // getTokenInBearer retrieves a access token from the authorization header diff --git a/session_test.go b/session_test.go index ea91ab697..44c5d37bb 100644 --- a/session_test.go +++ b/session_test.go @@ -124,7 +124,9 @@ func TestGetTokenInRequest(t *testing.T) { }) } } - access, bearer, err := getTokenInRequest(req, defaultName) + + access, bearer, err := getTokenInRequest(req, defaultName, true) + switch x.Error { case nil: assert.NoError(t, err, "case %d should not have thrown an error", i)