From 2961222a81b95ec843096f4f8c4a6f84dbb22ba8 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 ++ server_test.go | 1 + session.go | 39 ++++++++++++++++++++++++++------------- session_test.go | 4 +++- 6 files changed, 36 insertions(+), 14 deletions(-) diff --git a/config.go b/config.go index 080af6ad..28d4d9b4 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 b5cf9e5b..575fbb61 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 6ac8067a..5ee3c434 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/server_test.go b/server_test.go index 0fd25d6d..ac1c6bbe 100644 --- a/server_test.go +++ b/server_test.go @@ -447,6 +447,7 @@ func newFakeKeycloakConfig() *Config { CookieRefreshName: "kc-state", DisableAllLogging: true, DiscoveryURL: "127.0.0.1:0", + UseAuthorizationHeader: true, EnableAuthorizationCookies: true, EnableAuthorizationHeader: true, EnableLogging: false, diff --git a/session.go b/session.go index d58ce67b..6bd2594c 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,34 @@ 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 - } - if token, err = getTokenInCookie(req, name); err != nil { - return token, 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 + } } - bearer = false + + return token, bearer, nil + } + + // step: check for a token in cookie + token, err := getTokenInCookie(req, name) + if err != nil { + return token, false, err } - return token, bearer, nil + return token, false, nil } // getTokenInBearer retrieves a access token from the authorization header diff --git a/session_test.go b/session_test.go index ea91ab69..44c5d37b 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)