Skip to content
This repository has been archived by the owner on Jul 4, 2024. It is now read-only.

Commit

Permalink
Add client_user header into the Director's CORS config and update UI …
Browse files Browse the repository at this point in the history
…reference (#1742)

* Add client_user header into the Director's CORS config and update UI

* Bump Gateway version

* Make the client_user header configurable

* Add client_user header in the environment of the console deployment

* Bump Director version in values.yaml

* Change env name and revert gateway version bump

* Change the method for fetching env vals

* Rename header property

* Make gateway vs with cofigurable client_user header

* Make the header configurable in the gateway's secure vs
  • Loading branch information
Daniel Gospodinow authored Feb 26, 2021
1 parent 7c06500 commit 6f17938
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 34 deletions.
3 changes: 2 additions & 1 deletion chart/compass/charts/cockpit/templates/configmap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ data:
authority: 'https://dex.{{ .Values.global.ingress.domainName }}',
client_id: 'compass-ui',
scope: 'audience:server:client_id:compass-ui openid profile email groups',
}
},
clientIDHeaderKey: '{{ .Values.global.director.clientIDHeaderKey }}'
};
2 changes: 2 additions & 0 deletions chart/compass/charts/director/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ spec:
value: /config/config.yaml
- name: APP_ALLOW_JWT_SIGNING_NONE
value: {{ .Values.deployment.allowJWTSigningNone | quote }}
- name: APP_CLIENT_ID_HTTP_HEADER
value: {{ .Values.global.director.clientIDHeaderKey }}
- name: APP_OAUTH20_CLIENT_ENDPOINT
value: http://ory-hydra-admin.kyma-system.svc.cluster.local:4445/clients
- name: APP_OAUTH20_PUBLIC_ACCESS_TOKEN_ENDPOINT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ spec:
- "authorization"
- "content-type"
- "tenant"
- "client_user"
- {{ .Values.global.director.clientIDHeaderKey }}
allowMethods:
- "GET"
- "POST"
Expand Down
2 changes: 2 additions & 0 deletions chart/compass/charts/gateway/templates/virtualservice.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ spec:
- "authorization"
- "content-type"
- "tenant"
- {{ .Values.global.director.clientIDHeaderKey }}
allowMethods:
- "GET"
- match:
Expand All @@ -95,6 +96,7 @@ spec:
- "authorization"
- "content-type"
- "tenant"
- {{ .Values.global.director.clientIDHeaderKey }}
allowMethods:
- "GET"
- "POST"
Expand Down
6 changes: 4 additions & 2 deletions chart/compass/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ global:
version: "PR-1720"
director:
dir:
version: "PR-1738"
version: "PR-1742"
gateway:
dir:
version: "PR-1720"
Expand Down Expand Up @@ -51,7 +51,7 @@ global:
version: "PR-1726"
console:
dir:
version: "PR-12"
version: "PR-19"
tests:
director:
dir:
Expand Down Expand Up @@ -92,6 +92,8 @@ global:
prefix: /director
port: 3000

clientIDHeaderKey: client_user

tests:
scopes: "runtime:write application:write label_definition:write integration_system:write application:read runtime:read label_definition:read integration_system:read health_checks:read application_template:read application_template:write eventing:manage tenant:read automatic_scenario_assignment:read automatic_scenario_assignment:write"

Expand Down
9 changes: 5 additions & 4 deletions components/director/cmd/director/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,10 @@ type config struct {

MetricsAddress string `envconfig:"default=127.0.0.1:3001"`

JWKSEndpoint string `envconfig:"default=file://hack/default-jwks.json"`
JWKSSyncPeriod time.Duration `envconfig:"default=5m"`
AllowJWTSigningNone bool `envconfig:"default=true"`
JWKSEndpoint string `envconfig:"default=file://hack/default-jwks.json"`
JWKSSyncPeriod time.Duration `envconfig:"default=5m"`
AllowJWTSigningNone bool `envconfig:"default=true"`
ClientIDHttpHeaderKey string `envconfig:"default=client_user,APP_CLIENT_ID_HTTP_HEADER"`

RuntimeJWKSCachePeriod time.Duration `envconfig:"default=5m"`

Expand Down Expand Up @@ -190,7 +191,7 @@ func main() {
executableSchema := graphql.NewExecutableSchema(gqlCfg)

logger.Infof("Registering GraphQL endpoint on %s...", cfg.APIEndpoint)
authMiddleware := mp_authenticator.New(cfg.JWKSEndpoint, cfg.AllowJWTSigningNone)
authMiddleware := mp_authenticator.New(cfg.JWKSEndpoint, cfg.AllowJWTSigningNone, cfg.ClientIDHttpHeaderKey)

if cfg.JWKSSyncPeriod != 0 {
logger.Infof("JWKS synchronization enabled. Sync period: %v", cfg.JWKSSyncPeriod)
Expand Down
14 changes: 9 additions & 5 deletions components/director/internal/authenticator/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,22 @@ import (

const (
AuthorizationHeaderKey = "Authorization"
ClientUserHeader = "client_user"
)

type Authenticator struct {
jwksEndpoint string
allowJWTSigningNone bool
cachedJWKs *jwk.Set
clientIDHeaderKey string
mux sync.Mutex
}

func New(jwksEndpoint string, allowJWTSigningNone bool) *Authenticator {
return &Authenticator{jwksEndpoint: jwksEndpoint, allowJWTSigningNone: allowJWTSigningNone}
func New(jwksEndpoint string, allowJWTSigningNone bool, clientIDHeaderKey string) *Authenticator {
return &Authenticator{
jwksEndpoint: jwksEndpoint,
allowJWTSigningNone: allowJWTSigningNone,
clientIDHeaderKey: clientIDHeaderKey,
}
}

func (a *Authenticator) SynchronizeJWKS(ctx context.Context) error {
Expand Down Expand Up @@ -82,8 +86,8 @@ func (a *Authenticator) Handler() func(next http.Handler) http.Handler {

ctx = a.contextWithClaims(r.Context(), claims)

if clientUser := r.Header.Get(ClientUserHeader); clientUser != "" {
log.C(ctx).Infof("Found %s header in request with value: %s", ClientUserHeader, clientUser)
if clientUser := r.Header.Get(a.clientIDHeaderKey); clientUser != "" {
log.C(ctx).Infof("Found %s header in request with value: %s", a.clientIDHeaderKey, clientUser)
ctx = client.SaveToContext(ctx, clientUser)
}

Expand Down
47 changes: 26 additions & 21 deletions components/director/internal/authenticator/middleware_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,23 @@ import (
"github.com/stretchr/testify/require"
)

const defaultTenant = "af9f84a9-1d3a-4d9f-ae0c-94f883b33b6e"
const PublicJWKSURL = "file://testdata/jwks-public.json"
const PrivateJWKSURL = "file://testdata/jwks-private.json"
const PrivateJWKS2URL = "file://testdata/jwks-private2.json"
const PublicJWKS2URL = "file://testdata/jwks-public2.json"
const fakeJWKSURL = "file://testdata/invalid.json"
const (
AuthorizationHeaderKey = "Authorization"
ClientIDHeaderKey = "client_user"

defaultTenant = "af9f84a9-1d3a-4d9f-ae0c-94f883b33b6e"
PublicJWKSURL = "file://testdata/jwks-public.json"
PrivateJWKSURL = "file://testdata/jwks-private.json"
PrivateJWKS2URL = "file://testdata/jwks-private2.json"
PublicJWKS2URL = "file://testdata/jwks-public2.json"
fakeJWKSURL = "file://testdata/invalid.json"
)

func TestAuthenticator_SynchronizeJWKS(t *testing.T) {

t.Run("Success", func(t *testing.T) {
//given
auth := authenticator.New(PublicJWKSURL, true)
auth := authenticator.New(PublicJWKSURL, true, ClientIDHeaderKey)
//when
err := auth.SynchronizeJWKS(context.TODO())

Expand All @@ -53,7 +58,7 @@ func TestAuthenticator_SynchronizeJWKS(t *testing.T) {

t.Run("Error when can't fetch JWKS", func(t *testing.T) {
//given
authFake := authenticator.New(fakeJWKSURL, true)
authFake := authenticator.New(fakeJWKSURL, true, ClientIDHeaderKey)

//when
err := authFake.SynchronizeJWKS(context.TODO())
Expand All @@ -79,7 +84,7 @@ func TestAuthenticator_Handler(t *testing.T) {
req := fixEmptyRequest(t)

token := createTokenWithSigningMethod(t, defaultTenant, scopes, privateJWKS.Keys[0])
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token))
req.Header.Add(AuthorizationHeaderKey, fmt.Sprintf("Bearer %s", token))

//when
middleware(handler).ServeHTTP(rr, req)
Expand All @@ -98,7 +103,7 @@ func TestAuthenticator_Handler(t *testing.T) {

token := createNotSingedToken(t, defaultTenant, scopes)
require.NoError(t, err)
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token))
req.Header.Add(AuthorizationHeaderKey, fmt.Sprintf("Bearer %s", token))

//when
middleware(handler).ServeHTTP(rr, req)
Expand All @@ -117,8 +122,8 @@ func TestAuthenticator_Handler(t *testing.T) {
req := fixEmptyRequest(t)

token := createTokenWithSigningMethod(t, defaultTenant, scopes, privateJWKS.Keys[0])
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token))
req.Header.Add(authenticator.ClientUserHeader, clientUser)
req.Header.Add(AuthorizationHeaderKey, fmt.Sprintf("Bearer %s", token))
req.Header.Add(ClientIDHeaderKey, clientUser)

//when
middleware(handler).ServeHTTP(rr, req)
Expand All @@ -138,7 +143,7 @@ func TestAuthenticator_Handler(t *testing.T) {

token := createNotSingedToken(t, tnt, scopes)
require.NoError(t, err)
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token))
req.Header.Add(AuthorizationHeaderKey, fmt.Sprintf("Bearer %s", token))

//when
middleware(handler).ServeHTTP(rr, req)
Expand All @@ -150,7 +155,7 @@ func TestAuthenticator_Handler(t *testing.T) {

t.Run("Success - retry parsing token with synchronizing JWKS", func(t *testing.T) {
//given
auth := authenticator.New(PublicJWKSURL, false)
auth := authenticator.New(PublicJWKSURL, false, ClientIDHeaderKey)
err := auth.SynchronizeJWKS(context.TODO())
require.NoError(t, err)

Expand All @@ -166,7 +171,7 @@ func TestAuthenticator_Handler(t *testing.T) {
require.NoError(t, err)

token := createTokenWithSigningMethod(t, defaultTenant, scopes, privateJWKS2.Keys[0])
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token))
req.Header.Add(AuthorizationHeaderKey, fmt.Sprintf("Bearer %s", token))

//when
middleware(handler).ServeHTTP(rr, req)
Expand All @@ -178,7 +183,7 @@ func TestAuthenticator_Handler(t *testing.T) {

t.Run("Error - retry parsing token with failing synchronizing JWKS", func(t *testing.T) {
//given
auth := authenticator.New(PublicJWKSURL, false)
auth := authenticator.New(PublicJWKSURL, false, ClientIDHeaderKey)
err := auth.SynchronizeJWKS(context.TODO())
require.NoError(t, err)

Expand All @@ -194,7 +199,7 @@ func TestAuthenticator_Handler(t *testing.T) {
require.NoError(t, err)

token := createTokenWithSigningMethod(t, defaultTenant, scopes, privateJWKS2.Keys[0])
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token))
req.Header.Add(AuthorizationHeaderKey, fmt.Sprintf("Bearer %s", token))

//when
middleware(handler).ServeHTTP(rr, req)
Expand All @@ -218,7 +223,7 @@ func TestAuthenticator_Handler(t *testing.T) {
req := fixEmptyRequest(t)

token := createNotSingedToken(t, defaultTenant, scopes)
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token))
req.Header.Add(AuthorizationHeaderKey, fmt.Sprintf("Bearer %s", token))

//when
middleware(handler).ServeHTTP(rr, req)
Expand All @@ -241,7 +246,7 @@ func TestAuthenticator_Handler(t *testing.T) {
rr := httptest.NewRecorder()
req := fixEmptyRequest(t)

req.Header.Add("Authorization", "Bearer fake-token")
req.Header.Add(AuthorizationHeaderKey, "Bearer fake-token")

//when
middleware(handler).ServeHTTP(rr, req)
Expand Down Expand Up @@ -269,7 +274,7 @@ func TestAuthenticator_Handler(t *testing.T) {
req := fixEmptyRequest(t)

token := createTokenWithSigningMethod(t, defaultTenant, scopes, privateJWKS2.Keys[0])
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token))
req.Header.Add(AuthorizationHeaderKey, fmt.Sprintf("Bearer %s", token))

//when
middleware(handler).ServeHTTP(rr, req)
Expand Down Expand Up @@ -316,7 +321,7 @@ func createTokenWithSigningMethod(t *testing.T, tnt string, scopes string, key j
}

func createMiddleware(t *testing.T, allowJWTSigningNone bool) func(next http.Handler) http.Handler {
auth := authenticator.New(PublicJWKSURL, allowJWTSigningNone)
auth := authenticator.New(PublicJWKSURL, allowJWTSigningNone, ClientIDHeaderKey)
err := auth.SynchronizeJWKS(context.TODO())
require.NoError(t, err)
return auth.Handler()
Expand Down

0 comments on commit 6f17938

Please sign in to comment.