From dfa5e4bf21f80e69733d738359617ee030c767ab Mon Sep 17 00:00:00 2001 From: 7h3-3mp7y-m4n Date: Fri, 19 Jul 2024 18:24:28 +0530 Subject: [PATCH] InMemoryChannel ingress: Added the desire changes --- pkg/auth/token_verifier.go | 44 +++++++++++++++++++++++++++++++---- pkg/channel/event_receiver.go | 28 ++++++++++++++++++---- 2 files changed, 64 insertions(+), 8 deletions(-) diff --git a/pkg/auth/token_verifier.go b/pkg/auth/token_verifier.go index 1591238a927..3f2744b8f78 100644 --- a/pkg/auth/token_verifier.go +++ b/pkg/auth/token_verifier.go @@ -18,10 +18,12 @@ package auth import ( "context" + "encoding/base64" "encoding/json" "fmt" "io" "net/http" + "strings" "time" "github.com/coreos/go-oidc/v3/oidc" @@ -186,12 +188,46 @@ func (c *OIDCTokenVerifier) GetOIDCIdentity(ctx context.Context, r *http.Request if token == "" { return nil, fmt.Errorf("no JWT token found in request") } + parsedToken, err := ParseJWT(token) + if err != nil { + return nil, fmt.Errorf("failed to parse JWT: %v", err) + } + + var claims struct { + Issuer string `json:"iss"` + Audience []string `json:"aud"` + Subject string `json:"sub"` + Expiry int64 `json:"exp"` + IssuedAt int64 `json:"iat"` + } - // Verify the JWT token - oidcToken, err := c.VerifyJWT(ctx, token, audience) + if err := parsedToken.Claims(&claims); err != nil { + return nil, fmt.Errorf("failed to parse claims: %v", err) + } + + return &IDToken{ + Issuer: claims.Issuer, + Audience: claims.Audience, + Subject: claims.Subject, + Expiry: time.Unix(claims.Expiry, 0), + IssuedAt: time.Unix(claims.IssuedAt, 0), + }, nil +} +func ParseJWT(token string) (*oidc.IDToken, error) { + parts := strings.Split(token, ".") + if len(parts) != 3 { + return nil, fmt.Errorf("invalid JWT token format") + } + + payload, err := base64.RawURLEncoding.DecodeString(parts[1]) if err != nil { - return nil, fmt.Errorf("failed to verify JWT: %v", err) + return nil, fmt.Errorf("failed to decode JWT payload: %v", err) + } + + var claims oidc.IDToken + if err := json.Unmarshal(payload, &claims); err != nil { + return nil, fmt.Errorf("failed to unmarshal JWT claims: %v", err) } - return oidcToken, nil + return &claims, nil } diff --git a/pkg/channel/event_receiver.go b/pkg/channel/event_receiver.go index 07c5fc25322..75e9d9f655e 100644 --- a/pkg/channel/event_receiver.go +++ b/pkg/channel/event_receiver.go @@ -252,19 +252,24 @@ func (r *EventReceiver) ServeHTTP(response nethttp.ResponseWriter, request *neth return } + // Extract OIDC identity + _, err = r.ExtractOIDCIdentity(ctx, request) + if err != nil { + response.WriteHeader(nethttp.StatusUnauthorized) + return + } + /// Here we do the OIDC audience verification features := feature.FromContext(ctx) if features.IsOIDCAuthentication() { r.logger.Debug("OIDC authentication is enabled") - oidcToken, err := r.tokenVerifier.GetOIDCIdentity(ctx, request, r.audience) + err = r.tokenVerifier.VerifyJWTFromRequest(ctx, request, &r.audience, response) if err != nil { r.logger.Warn("Error when validating the JWT token in the request", zap.Error(err)) - response.WriteHeader(nethttp.StatusUnauthorized) return } - r.logger.Debug("Request contained a valid JWT. Continuing...", zap.String("subject", oidcToken.Subject)) + r.logger.Debug("Request contained a valid JWT. Continuing...") } - err = r.receiverFunc(request.Context(), channel, *event, utils.PassThroughHeaders(request.Header)) if err != nil { if _, ok := err.(*UnknownChannelError); ok { @@ -290,3 +295,18 @@ func ReportEventCountMetricsForDispatchError(err error, reporter StatsReporter, } var _ nethttp.Handler = (*EventReceiver)(nil) + +func (r *EventReceiver) ExtractOIDCIdentity(ctx context.Context, request *nethttp.Request) (*auth.IDToken, error) { + if r.tokenVerifier == nil { + return nil, nil + } + + identity, err := r.tokenVerifier.GetOIDCIdentity(ctx, request, r.audience) + if err != nil { + r.logger.Warn("Error getting OIDC identity", zap.Error(err)) + return nil, err + } + + r.logger.Debug("Successfully retrieved OIDC identity", zap.String("identity", identity.Subject)) + return identity, nil +}