github.com/hellofresh/janus@v0.0.0-20230925145208-ce8de8183c67/pkg/plugin/oauth2/jwt_manager.go (about) 1 package oauth2 2 3 import ( 4 "context" 5 6 jwtBase "github.com/dgrijalva/jwt-go" 7 "github.com/hellofresh/janus/pkg/jwt" 8 "github.com/hellofresh/janus/pkg/metrics" 9 obs "github.com/hellofresh/janus/pkg/observability" 10 "github.com/hellofresh/stats-go/bucket" 11 "github.com/hellofresh/stats-go/client" 12 log "github.com/sirupsen/logrus" 13 "go.opencensus.io/stats" 14 "go.opencensus.io/tag" 15 ) 16 17 // JWTManager is responsible for managing the JWT tokens 18 type JWTManager struct { 19 parser *jwt.Parser 20 } 21 22 // NewJWTManager creates a new instance of JWTManager 23 func NewJWTManager(parser *jwt.Parser) *JWTManager { 24 return &JWTManager{parser} 25 } 26 27 // IsKeyAuthorized checks if the access token is valid 28 func (m *JWTManager) IsKeyAuthorized(ctx context.Context, accessToken string) bool { 29 if ctx == nil { 30 return false 31 } 32 33 stats := metrics.WithContext(ctx) 34 if stats == nil { 35 return false 36 } 37 38 if _, err := m.parser.Parse(accessToken); err != nil { 39 log.WithError(err).Info("Failed to parse and validate the JWT") 40 41 switch jwtErr := err.(type) { 42 case *jwtBase.ValidationError: 43 shouldReport(ctx, stats, jwtErr.Errors&jwtBase.ValidationErrorExpired != 0, "ValidationErrorExpired") 44 shouldReport(ctx, stats, jwtErr.Errors&jwtBase.ValidationErrorClaimsInvalid != 0, "ValidationErrorClaimsInvalid") 45 shouldReport(ctx, stats, jwtErr.Errors&jwtBase.ValidationErrorIssuedAt != 0, "ValidationErrorIssuedAt") 46 shouldReport(ctx, stats, jwtErr.Errors&jwtBase.ValidationErrorNotValidYet != 0, "ValidationErrorNotValidYet") 47 shouldReport(ctx, stats, jwtErr.Errors&jwtBase.ValidationErrorIssuer != 0, "ValidationErrorIssuer") 48 shouldReport(ctx, stats, jwtErr.Errors&jwtBase.ValidationErrorMalformed != 0, "ValidationErrorMalformed") 49 shouldReport(ctx, stats, jwtErr.Errors&jwtBase.ValidationErrorSignatureInvalid != 0, "ValidationErrorSignatureInvalid") 50 shouldReport(ctx, stats, jwtErr.Errors&jwtBase.ValidationErrorUnverifiable != 0, "ValidationErrorUnverifiable") 51 return false 52 default: 53 shouldReport(ctx, stats, true, "ErrFailedToParse") 54 return false 55 } 56 } 57 58 return true 59 } 60 61 func shouldReport(ctx context.Context, client client.Client, typeCheck bool, operation string) { 62 if typeCheck { 63 client.TrackMetric("tokens", bucket.MetricOperation{"jwt-manager", "parse-error", operation}) 64 65 // OpenCensus stats 66 ctx, _ := tag.New(ctx, tag.Insert(obs.KeyJWTValidationErrorType, operation)) 67 stats.Record(ctx, obs.MJWTManagerValidationErrors.M(1)) 68 69 } 70 }