From a9da6ce1d58df30644443ddaaf1bb6412a516856 Mon Sep 17 00:00:00 2001 From: Charandas Date: Tue, 7 May 2024 11:20:16 -0700 Subject: [PATCH] ext_jwt: streamline expected aud in access tokens and id tokens (#87401) --- pkg/services/authn/clients/ext_jwt.go | 17 +++++++---------- pkg/services/authn/clients/ext_jwt_test.go | 13 ++++++------- pkg/setting/setting_jwt.go | 8 +++----- 3 files changed, 16 insertions(+), 22 deletions(-) diff --git a/pkg/services/authn/clients/ext_jwt.go b/pkg/services/authn/clients/ext_jwt.go index c0ecc43d530..97ea29fdd8d 100644 --- a/pkg/services/authn/clients/ext_jwt.go +++ b/pkg/services/authn/clients/ext_jwt.go @@ -21,25 +21,22 @@ import ( var _ authn.Client = new(ExtendedJWT) const ( - rfc9068ShortMediaType = "at+jwt" - extJWTAuthenticationHeaderName = "X-Access-Token" - extJWTAuthorizationHeaderName = "X-Grafana-Id" + extJWTAuthenticationHeaderName = "X-Access-Token" + extJWTAuthorizationHeaderName = "X-Grafana-Id" + extJWTAccessTokenExpectAudience = "grafana" ) func ProvideExtendedJWT(userService user.Service, cfg *setting.Cfg, signingKeys signingkeys.Service) *ExtendedJWT { verifier := authlib.NewAccessTokenVerifier(authlib.VerifierConfig{ - SigningKeysURL: cfg.ExtJWTAuth.JWKSUrl, - AllowedAudiences: []string{ - cfg.ExtJWTAuth.ExpectAudience, - }, + SigningKeysURL: cfg.ExtJWTAuth.JWKSUrl, + AllowedAudiences: []string{extJWTAccessTokenExpectAudience}, }) + // For ID tokens, we explicitly do not validate audience, hence an empty AllowedAudiences + // Namespace claim will be checked idTokenVerifier := authlib.NewIDTokenVerifier(authlib.VerifierConfig{ SigningKeysURL: cfg.ExtJWTAuth.JWKSUrl, - AllowedAudiences: []string{ - cfg.ExtJWTAuth.ExpectAudience, - }, }) return &ExtendedJWT{ diff --git a/pkg/services/authn/clients/ext_jwt_test.go b/pkg/services/authn/clients/ext_jwt_test.go index 62b29b2efcc..a023aefdfdb 100644 --- a/pkg/services/authn/clients/ext_jwt_test.go +++ b/pkg/services/authn/clients/ext_jwt_test.go @@ -38,7 +38,7 @@ var ( Claims: &jwt.Claims{ Issuer: "http://localhost:3000", Subject: "access-policy:this-uid", - Audience: jwt.Audience{"http://localhost:3000"}, + Audience: jwt.Audience{extJWTAccessTokenExpectAudience}, ID: "1234567890", Expiry: jwt.NewNumericDate(time.Date(2023, 5, 3, 0, 0, 0, 0, time.UTC)), IssuedAt: jwt.NewNumericDate(time.Date(2023, 5, 2, 0, 0, 0, 0, time.UTC)), @@ -54,7 +54,7 @@ var ( Claims: &jwt.Claims{ Issuer: "http://localhost:3000", Subject: "user:2", - Audience: jwt.Audience{"http://localhost:3000"}, + Audience: jwt.Audience{"stack:1"}, ID: "1234567890", Expiry: jwt.NewNumericDate(time.Date(2023, 5, 3, 0, 0, 0, 0, time.UTC)), IssuedAt: jwt.NewNumericDate(time.Date(2023, 5, 2, 0, 0, 0, 0, time.UTC)), @@ -68,7 +68,7 @@ var ( Claims: &jwt.Claims{ Issuer: "http://localhost:3000", Subject: "access-policy:this-uid", - Audience: jwt.Audience{"http://localhost:3000"}, + Audience: jwt.Audience{extJWTAccessTokenExpectAudience}, ID: "1234567890", Expiry: jwt.NewNumericDate(time.Date(2023, 5, 3, 0, 0, 0, 0, time.UTC)), IssuedAt: jwt.NewNumericDate(time.Date(2023, 5, 2, 0, 0, 0, 0, time.UTC)), @@ -81,7 +81,7 @@ var ( Claims: &jwt.Claims{ Issuer: "http://localhost:3000", Subject: "user:2", - Audience: jwt.Audience{"http://localhost:3000"}, + Audience: jwt.Audience{"stack:1234"}, ID: "1234567890", Expiry: jwt.NewNumericDate(time.Date(2023, 5, 3, 0, 0, 0, 0, time.UTC)), IssuedAt: jwt.NewNumericDate(time.Date(2023, 5, 2, 0, 0, 0, 0, time.UTC)), @@ -530,9 +530,8 @@ func setupTestCtx(cfg *setting.Cfg) *testEnv { cfg = &setting.Cfg{ // default org set up by the authenticator is 1 ExtJWTAuth: setting.ExtJWTSettings{ - Enabled: true, - ExpectIssuer: "http://localhost:3000", - ExpectAudience: "http://localhost:3000", + Enabled: true, + ExpectIssuer: "http://localhost:3000", }, } } diff --git a/pkg/setting/setting_jwt.go b/pkg/setting/setting_jwt.go index 6f8bb21fae2..bbc7e3612e6 100644 --- a/pkg/setting/setting_jwt.go +++ b/pkg/setting/setting_jwt.go @@ -26,17 +26,15 @@ type AuthJWTSettings struct { } type ExtJWTSettings struct { - Enabled bool - ExpectIssuer string - ExpectAudience string - JWKSUrl string + Enabled bool + ExpectIssuer string + JWKSUrl string } func (cfg *Cfg) readAuthExtJWTSettings() { authExtendedJWT := cfg.SectionWithEnvOverrides("auth.extended_jwt") jwtSettings := ExtJWTSettings{} jwtSettings.Enabled = authExtendedJWT.Key("enabled").MustBool(false) - jwtSettings.ExpectAudience = authExtendedJWT.Key("expect_audience").MustString("") jwtSettings.JWKSUrl = authExtendedJWT.Key("jwks_url").MustString("") cfg.ExtJWTAuth = jwtSettings }