From 341f76ddd3944b8589766640589b45ec635f9b20 Mon Sep 17 00:00:00 2001 From: Richard87 Date: Wed, 9 Oct 2024 10:18:42 +0200 Subject: [PATCH 1/6] Add UncheckedValidator and use it temporarily --- api/utils/token/unchecked_principal.go | 52 ++++++++++++++++++++++++++ api/utils/token/unchecked_validator.go | 36 ++++++++++++++++++ main.go | 5 ++- 3 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 api/utils/token/unchecked_principal.go create mode 100644 api/utils/token/unchecked_validator.go diff --git a/api/utils/token/unchecked_principal.go b/api/utils/token/unchecked_principal.go new file mode 100644 index 00000000..61b9a2b2 --- /dev/null +++ b/api/utils/token/unchecked_principal.go @@ -0,0 +1,52 @@ +package token + +import ( + "context" + "fmt" + + "github.com/go-jose/go-jose/v4/jwt" +) + +func (c *unchechedClaimsPrincipal) Validate(_ context.Context) error { + return nil +} + +type unchechedClaimsPrincipal struct { + token string + claims *jwt.Claims + azureClaims *azureClaims +} + +func (p *unchechedClaimsPrincipal) Token() string { + return p.token +} +func (p *unchechedClaimsPrincipal) IsAuthenticated() bool { + return true +} +func (p *unchechedClaimsPrincipal) Id() string { + if p.azureClaims.ObjectId != "" { + return fmt.Sprintf("unverified: %s", p.azureClaims.ObjectId) + } + + return fmt.Sprintf("unverified: %s (sub!)", p.claims.Subject) +} + +func (p *unchechedClaimsPrincipal) Name() string { + if p.azureClaims.Upn != "" { + return fmt.Sprintf("unverified: %s", p.azureClaims.Upn) + } + + if p.azureClaims.AppDisplayName != "" { + return fmt.Sprintf("unverified: %s", p.azureClaims.AppDisplayName) + } + + if p.azureClaims.AppId != "" { + return fmt.Sprintf("unverified: %s", p.azureClaims.AppId) + } + + if p.azureClaims.ObjectId != "" { + return fmt.Sprintf("unverified: %s", p.azureClaims.ObjectId) + } + + return fmt.Sprintf("unverified: %s", p.claims.Subject) +} diff --git a/api/utils/token/unchecked_validator.go b/api/utils/token/unchecked_validator.go new file mode 100644 index 00000000..5a76deca --- /dev/null +++ b/api/utils/token/unchecked_validator.go @@ -0,0 +1,36 @@ +package token + +import ( + "context" + "fmt" + "net/url" + + "github.com/equinor/radix-common/net/http" + "github.com/go-jose/go-jose/v4" + "github.com/go-jose/go-jose/v4/jwt" +) + +type UncheckedValidator struct{} + +var _ ValidatorInterface = &UncheckedValidator{} + +func NewUncheckedValidator(_ *url.URL, _ string) (*UncheckedValidator, error) { + return &UncheckedValidator{}, nil +} + +func (v *UncheckedValidator) ValidateToken(_ context.Context, token string) (TokenPrincipal, error) { + var registeredClaims jwt.Claims + var azureClaims azureClaims + + jwt, err := jwt.ParseSigned(token, []jose.SignatureAlgorithm{jose.HS256, jose.RS256}) + if err != nil { + return nil, http.ForbiddenError("invalid token") + } + err = jwt.UnsafeClaimsWithoutVerification(®isteredClaims, &azureClaims) + if err != nil { + return nil, http.ForbiddenError(fmt.Sprintf("failed to extract JWT unsafeClaims: %w", err)) + } + + principal := &unchechedClaimsPrincipal{token: token, claims: ®isteredClaims, azureClaims: &azureClaims} + return principal, nil +} diff --git a/main.go b/main.go index 65a4f041..c6848f57 100644 --- a/main.go +++ b/main.go @@ -76,14 +76,15 @@ func initializeServer(c config.Config) *http.Server { return srv } -func initializeTokenValidator(c config.Config) *token.Validator { +func initializeTokenValidator(c config.Config) token.ValidatorInterface { issuerUrl, err := url.Parse(c.OidcIssuer) if err != nil { log.Fatal().Err(err).Msg("Error parsing issuer url") } // Set up the validator. - jwtValidator, err := token.NewValidator(issuerUrl, c.OidcAudience) + // jwtValidator, err := token.NewValidator(issuerUrl, c.OidcAudience) + jwtValidator, err := token.NewUncheckedValidator(issuerUrl, c.OidcAudience) if err != nil { log.Fatal().Err(err).Msg("Error creating JWT validator") } From 2a6ec340316d172c6bf5dad205b90d758b7fb12a Mon Sep 17 00:00:00 2001 From: Richard87 Date: Wed, 9 Oct 2024 10:39:03 +0200 Subject: [PATCH 2/6] fix linting --- api/utils/token/unchecked_validator.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/utils/token/unchecked_validator.go b/api/utils/token/unchecked_validator.go index 5a76deca..1dd408e9 100644 --- a/api/utils/token/unchecked_validator.go +++ b/api/utils/token/unchecked_validator.go @@ -28,7 +28,7 @@ func (v *UncheckedValidator) ValidateToken(_ context.Context, token string) (Tok } err = jwt.UnsafeClaimsWithoutVerification(®isteredClaims, &azureClaims) if err != nil { - return nil, http.ForbiddenError(fmt.Sprintf("failed to extract JWT unsafeClaims: %w", err)) + return nil, http.ForbiddenError(fmt.Sprintf("failed to extract JWT unsafeClaims: %s", err.Error())) } principal := &unchechedClaimsPrincipal{token: token, claims: ®isteredClaims, azureClaims: &azureClaims} From 4db576a048b31e137085e65c64aa8984e1a7fea5 Mon Sep 17 00:00:00 2001 From: Richard87 Date: Wed, 9 Oct 2024 10:39:45 +0200 Subject: [PATCH 3/6] go mod tidy --- go.mod | 1 + go.sum | 2 ++ 2 files changed, 3 insertions(+) diff --git a/go.mod b/go.mod index 4dac852e..779efce1 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,7 @@ require ( github.com/equinor/radix-operator v1.61.0 github.com/evanphx/json-patch/v5 v5.9.0 github.com/felixge/httpsnoop v1.0.4 + github.com/go-jose/go-jose/v4 v4.0.2 github.com/golang/mock v1.6.0 github.com/google/uuid v1.6.0 github.com/gorilla/mux v1.8.1 diff --git a/go.sum b/go.sum index a21e0507..21db3d4f 100644 --- a/go.sum +++ b/go.sum @@ -107,6 +107,8 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-jose/go-jose/v4 v4.0.2 h1:R3l3kkBds16bO7ZFAEEcofK0MkrAJt3jlJznWZG0nvk= +github.com/go-jose/go-jose/v4 v4.0.2/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= From d125ae7f5131958b225d2fb457cb5a5cd90bac90 Mon Sep 17 00:00:00 2001 From: Richard87 Date: Wed, 9 Oct 2024 10:44:51 +0200 Subject: [PATCH 4/6] josejwt --- api/utils/token/unchecked_validator.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/api/utils/token/unchecked_validator.go b/api/utils/token/unchecked_validator.go index 1dd408e9..4446be22 100644 --- a/api/utils/token/unchecked_validator.go +++ b/api/utils/token/unchecked_validator.go @@ -7,7 +7,7 @@ import ( "github.com/equinor/radix-common/net/http" "github.com/go-jose/go-jose/v4" - "github.com/go-jose/go-jose/v4/jwt" + josejwt "github.com/go-jose/go-jose/v4/jwt" ) type UncheckedValidator struct{} @@ -19,10 +19,10 @@ func NewUncheckedValidator(_ *url.URL, _ string) (*UncheckedValidator, error) { } func (v *UncheckedValidator) ValidateToken(_ context.Context, token string) (TokenPrincipal, error) { - var registeredClaims jwt.Claims + var registeredClaims josejwt.Claims var azureClaims azureClaims - jwt, err := jwt.ParseSigned(token, []jose.SignatureAlgorithm{jose.HS256, jose.RS256}) + jwt, err := josejwt.ParseSigned(token, []jose.SignatureAlgorithm{jose.HS256, jose.RS256}) if err != nil { return nil, http.ForbiddenError("invalid token") } From 13ad01bc6f19877e9703c70c42df44399d632af2 Mon Sep 17 00:00:00 2001 From: Richard87 Date: Wed, 9 Oct 2024 11:13:46 +0200 Subject: [PATCH 5/6] cleanup names --- api/middleware/auth/authentication.go | 2 +- api/utils/token/unchecked_principal.go | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/api/middleware/auth/authentication.go b/api/middleware/auth/authentication.go index ac2ce272..b722bc9b 100644 --- a/api/middleware/auth/authentication.go +++ b/api/middleware/auth/authentication.go @@ -94,7 +94,7 @@ func NewZerologAuthenticationDetailsMiddleware() negroni.HandlerFunc { logContext := log.Ctx(ctx).With() if user.IsAuthenticated() { - logContext = logContext.Str("azure_oid", user.Id()) + logContext = logContext.Str("user_id", user.Id()) } else { logContext = logContext.Bool("anonymous", true) } diff --git a/api/utils/token/unchecked_principal.go b/api/utils/token/unchecked_principal.go index 61b9a2b2..8073d857 100644 --- a/api/utils/token/unchecked_principal.go +++ b/api/utils/token/unchecked_principal.go @@ -25,28 +25,28 @@ func (p *unchechedClaimsPrincipal) IsAuthenticated() bool { } func (p *unchechedClaimsPrincipal) Id() string { if p.azureClaims.ObjectId != "" { - return fmt.Sprintf("unverified: %s", p.azureClaims.ObjectId) + return fmt.Sprintf("oid:%s", p.azureClaims.ObjectId) } - return fmt.Sprintf("unverified: %s (sub!)", p.claims.Subject) + return fmt.Sprintf("sub:%s", p.claims.Subject) } func (p *unchechedClaimsPrincipal) Name() string { if p.azureClaims.Upn != "" { - return fmt.Sprintf("unverified: %s", p.azureClaims.Upn) + return p.azureClaims.Upn } if p.azureClaims.AppDisplayName != "" { - return fmt.Sprintf("unverified: %s", p.azureClaims.AppDisplayName) + return p.azureClaims.AppDisplayName } if p.azureClaims.AppId != "" { - return fmt.Sprintf("unverified: %s", p.azureClaims.AppId) + return p.azureClaims.AppId } if p.azureClaims.ObjectId != "" { - return fmt.Sprintf("unverified: %s", p.azureClaims.ObjectId) + return p.azureClaims.ObjectId } - return fmt.Sprintf("unverified: %s", p.claims.Subject) + return p.claims.Subject } From 1f3f1b2b1933bbadb7bafe1e075cb76224e39f80 Mon Sep 17 00:00:00 2001 From: Richard87 Date: Wed, 9 Oct 2024 11:15:04 +0200 Subject: [PATCH 6/6] update operator --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 779efce1..23fb4970 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/cert-manager/cert-manager v1.15.0 github.com/equinor/radix-common v1.9.5 github.com/equinor/radix-job-scheduler v1.11.0 - github.com/equinor/radix-operator v1.61.0 + github.com/equinor/radix-operator v1.62.0 github.com/evanphx/json-patch/v5 v5.9.0 github.com/felixge/httpsnoop v1.0.4 github.com/go-jose/go-jose/v4 v4.0.2 diff --git a/go.sum b/go.sum index 21db3d4f..d3fb7c3f 100644 --- a/go.sum +++ b/go.sum @@ -91,6 +91,8 @@ github.com/equinor/radix-job-scheduler v1.11.0 h1:8wCmXOVl/1cto8q2WJQEE06Cw68/Qm github.com/equinor/radix-job-scheduler v1.11.0/go.mod h1:yPXn3kDcMY0Z3kBkosjuefsdY1x2g0NlBeybMmHz5hc= github.com/equinor/radix-operator v1.61.0 h1:kHWHn5p9S+wKqOTSKtju2URW5FKgAFng1p6RLRnaTmE= github.com/equinor/radix-operator v1.61.0/go.mod h1:uRW9SgVZ94hkpq87npVv2YVviRuXNJ1zgCleya1uvr8= +github.com/equinor/radix-operator v1.62.0 h1:lurDVymrDhlyopd46KMV28eUltrVUPCk3bnBRFuyCsU= +github.com/equinor/radix-operator v1.62.0/go.mod h1:uRW9SgVZ94hkpq87npVv2YVviRuXNJ1zgCleya1uvr8= github.com/evanphx/json-patch v5.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lShz4oaXpDTX2bLe7ls= github.com/evanphx/json-patch v5.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg=