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

Upstream Token Header #247

Merged
merged 1 commit into from
Jul 6, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ FEATURES
* added the --skip-client-id option to permit skipping the verification of the auduence against client in token [#PR236](https://github.com/gambol99/keycloak-proxy/pull/236)
* updated the base image to apline 3.6 in commit [0fdebaf821](https://github.com/gambol99/keycloak-proxy/pull/236/commits/0fdebaf8215e9480896f01ec7ab2ef7caa242da1)
* moved to use zap for the logging [#PR237](https://github.com/gambol99/keycloak-proxy/pull/237)
* making the X-Auth-Token optional in the upstream headers via the --enable-token-header [#PR247](https://github.com/gambol99/keycloak-proxy/pull/247)

BREAKING CHANGES:
* the proxy no longer uses prefixes for resources, if you wish to use wildcard urls you need
Expand Down
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ USAGE:
keycloak-proxy [options]

VERSION:
v2.1.0 (git+sha: 960c2e5-dirty, built: 25/04/2017)
v2.1.0-rc2 (git+sha: 6782490-dirty, built: 06-07-2017)

AUTHOR:
Rohith <[email protected]>
Expand All @@ -55,7 +55,8 @@ GLOBAL OPTIONS:
--upstream-url value url for the upstream endpoint you wish to proxy [$PROXY_UPSTREAM_URL]
--resources value list of resources 'uri=/admin|methods=GET,PUT|roles=role1,role2'
--headers value custom headers to the upstream request, key=value
--enable-encrypted-token indicates you want the access token encrypted (default: false)
--enable-token-header enables the token authentication header X-Auth-Token to upstream (default: true)
--enable-encrypted-token enable encryption for the access tokens (default: false)
--enable-logging enable http logging of the requests (default: false)
--enable-json-logging switch on json logging rather than text (default: false)
--enable-forwarding enables the forwarding proxy mode, signing outbound request (default: false)
Expand Down Expand Up @@ -85,6 +86,7 @@ GLOBAL OPTIONS:
--tls-ca-key value path the ca private key, used by the forward signing proxy
--tls-client-certificate value path to the client certificate for outbound connections in reverse and forwarding proxy modes
--skip-upstream-tls-verify skip the verification of any upstream TLS (default: true)
--skip-client-id skip the check on the client token (default: false)
--cors-origins value origins to add to the CORE origins control (Access-Control-Allow-Origin)
--cors-methods value methods permitted in the access control (Access-Control-Allow-Methods)
--cors-headers value set of headers to add to the CORS access control (Access-Control-Allow-Headers)
Expand All @@ -107,6 +109,7 @@ GLOBAL OPTIONS:
--forwarding-username value username to use when logging into the openid provider
--forwarding-password value password to use when logging into the openid provider
--forwarding-domains value list of domains which should be signed; everything else is relayed unsigned
--disable-all-logging disables all logging to stdout and stderr (default: false)
--help, -h show help
--version, -v print the version
```
Expand Down
1 change: 1 addition & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ func newDefaultConfig() *Config {
UpstreamTimeout: time.Duration(10) * time.Second,
UpstreamKeepaliveTimeout: time.Duration(10) * time.Second,
EnableAuthorizationHeader: true,
EnableTokenHeader: true,
CookieAccessName: "kc-access",
CookieRefreshName: "kc-state",
SecureCookie: true,
Expand Down
2 changes: 2 additions & 0 deletions doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ type Config struct {
// Headers permits adding customs headers across the board
Headers map[string]string `json:"headers" yaml:"headers" usage:"custom headers to the upstream request, key=value"`

// EnableTokenHeader adds the JWT token to the upstream authentication headers
EnableTokenHeader bool `json:"enable-token-header" yaml:"enable-token-header" usage:"enables the token authentication header X-Auth-Token to upstream"`
// EnableEncryptedToken indicates the access token should be encoded
EnableEncryptedToken bool `json:"enable-encrypted-token" yaml:"enable-encrypted-token" usage:"enable encryption for the access tokens"`
// EnableLogging indicates if we should log all the requests
Expand Down
9 changes: 5 additions & 4 deletions middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ import (
const (
// normalizeFlags is the options to purell
normalizeFlags purell.NormalizationFlags = purell.FlagRemoveDotSegments | purell.FlagRemoveDuplicateSlashes
// httpResponseName is the name of the http response hanlder
httpResponseName = "http.response"
)

// entrypointMiddleware is custom filtering for incoming requests
Expand Down Expand Up @@ -328,14 +326,17 @@ func (r *oauthProxy) headersMiddleware(custom []string) func(http.Handler) http.
req.Header.Set("X-Auth-ExpiresIn", user.expiresAt.String())
req.Header.Set("X-Auth-Roles", strings.Join(user.roles, ","))
req.Header.Set("X-Auth-Subject", user.id)
req.Header.Set("X-Auth-Token", user.token.Encode())
req.Header.Set("X-Auth-Userid", user.name)
req.Header.Set("X-Auth-Username", user.name)

// should we add the token header?
if r.config.EnableTokenHeader {
req.Header.Set("X-Auth-Token", user.token.Encode())
}
// add the authorization header if requested
if r.config.EnableAuthorizationHeader {
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", user.token.Encode()))
}

// inject any custom claims
for claim, header := range customClaims {
if claim, found := user.claims[claim]; found {
Expand Down
41 changes: 41 additions & 0 deletions server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,46 @@ func TestSkipClientIDEnabled(t *testing.T) {
p.RunTests(t, requests)
}

func TestAuthTokenHeaderEnabled(t *testing.T) {
p := newFakeProxy(nil)
token := newTestToken(p.idp.getLocation())
signed, _ := p.idp.signToken(token.claims)

requests := []fakeRequest{
{
URI: "/auth_all/test",
RawToken: signed.Encode(),
ExpectedProxyHeaders: map[string]string{
"X-Auth-Token": signed.Encode(),
},
ExpectedProxy: true,
ExpectedCode: http.StatusOK,
},
}
p.RunTests(t, requests)
}

func TestAuthTokenHeaderDisabled(t *testing.T) {
c := newFakeKeycloakConfig()
c.EnableTokenHeader = false
p := newFakeProxy(c)
token := newTestToken(p.idp.getLocation())
signed, _ := p.idp.signToken(token.claims)

requests := []fakeRequest{
{
URI: "/auth_all/test",
RawToken: signed.Encode(),
ExpectedProxyHeaders: map[string]string{
"X-Auth-Token": "",
},
ExpectedProxy: true,
ExpectedCode: http.StatusOK,
},
}
p.RunTests(t, requests)
}

func newTestService() string {
_, _, u := newTestProxyService(nil)
return u
Expand Down Expand Up @@ -344,6 +384,7 @@ func newFakeKeycloakConfig() *Config {
EnableAuthorizationHeader: true,
EnableLogging: false,
EnableLoginHandler: true,
EnableTokenHeader: true,
Listen: "127.0.0.1:0",
Scopes: []string{},
Verbose: true,
Expand Down