diff options
| author | mo khan <mo@mokhan.ca> | 2025-05-20 14:28:06 -0600 |
|---|---|---|
| committer | mo khan <mo@mokhan.ca> | 2025-05-23 14:49:19 -0600 |
| commit | 4beee46dc6c7642316e118a4d3aa51e4b407256e (patch) | |
| tree | 039bdf57b99061844aeb0fe55ad0bc1c864166af /app/middleware/user.go | |
| parent | 0ba49bfbde242920d8675a193d7af89420456fc0 (diff) | |
feat: add external authorization service (authzd) with JWT authentication
- Add new authzd gRPC service implementing Envoy's external authorization API
- Integrate JWT authentication filter in Envoy configuration with claim extraction
- Update middleware to support both cookie-based and header-based user authentication
- Add comprehensive test coverage for authorization service and server
- Configure proper service orchestration with authzd, sparkled, and Envoy
- Update build system and Docker configuration for multi-service deployment
- Add grpcurl tool for gRPC service debugging and testing
This enables fine-grained authorization control through Envoy's ext_authz filter
while maintaining backward compatibility with existing cookie-based authentication.
Diffstat (limited to 'app/middleware/user.go')
| -rw-r--r-- | app/middleware/user.go | 24 |
1 files changed, 15 insertions, 9 deletions
diff --git a/app/middleware/user.go b/app/middleware/user.go index 9a88f8e..6c018f4 100644 --- a/app/middleware/user.go +++ b/app/middleware/user.go @@ -14,20 +14,26 @@ import ( func User(db domain.Repository[*domain.User]) func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - idToken := cfg.IDToken.From(r.Context()) - if x.IsZero(idToken) { - next.ServeHTTP(w, r) - return - } + subject := r.Header.Get("x-jwt-claim-sub") + user := db.Find(r.Context(), domain.ID(subject)) - user := db.Find(r.Context(), domain.ID(idToken.Subject)) if !x.IsPresent(user) { - user = mapper.MapFrom[*oidc.IDToken, *domain.User](idToken) - if err := db.Save(r.Context(), user); err != nil { - pls.LogError(r.Context(), err) + idToken := cfg.IDToken.From(r.Context()) + + if x.IsZero(idToken) { next.ServeHTTP(w, r) return } + + user = db.Find(r.Context(), domain.ID(idToken.Subject)) + if !x.IsPresent(user) { + user = mapper.MapFrom[*oidc.IDToken, *domain.User](idToken) + if err := db.Save(r.Context(), user); err != nil { + pls.LogError(r.Context(), err) + next.ServeHTTP(w, r) + return + } + } } next.ServeHTTP(w, r.WithContext(cfg.CurrentUser.With(r.Context(), user))) |
