pomerium/internal/middleware/middleware.go
Joe Kralicky 396c35b6b4
New tracing system (#5388)
* update tracing config definitions

* new tracing system

* performance improvements

* only configure tracing in envoy if it is enabled in pomerium

* [tracing] refactor to use custom extension for trace id editing (#5420)

refactor to use custom extension for trace id editing

* set default tracing sample rate to 1.0

* fix proxy service http middleware

* improve some existing auth related traces

* test fixes

* bump envoyproxy/go-control-plane

* code cleanup

* test fixes

* Fix missing spans for well-known endpoints

* import extension apis from pomerium/envoy-custom
2025-01-21 13:26:32 -05:00

70 lines
2.3 KiB
Go

package middleware
import (
"crypto/sha256"
"crypto/subtle"
"net/http"
"github.com/pomerium/pomerium/internal/httputil"
"github.com/pomerium/pomerium/internal/urlutil"
)
// SetHeaders sets a map of response headers.
func SetHeaders(headers map[string]string) func(next http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
for key, val := range headers {
w.Header().Set(key, val)
}
next.ServeHTTP(w, r)
})
}
}
// ValidateSignature ensures the request is valid and has been signed with
// the corresponding client secret key
func ValidateSignature(sharedKey []byte) func(next http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return httputil.HandlerFunc(func(w http.ResponseWriter, r *http.Request) error {
if err := ValidateRequestURL(r, sharedKey); err != nil {
return httputil.NewError(http.StatusBadRequest, err)
}
next.ServeHTTP(w, r)
return nil
})
}
}
// ValidateRequestURL validates the current absolute request URL was signed
// by a given shared key.
func ValidateRequestURL(r *http.Request, key []byte) error {
return urlutil.NewSignedURL(key, urlutil.GetAbsoluteURL(r)).Validate()
}
// RequireBasicAuth creates a new handler that requires basic auth from the client before
// calling the underlying handler.
func RequireBasicAuth(username, password string) func(next http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
u, p, ok := r.BasicAuth()
if !ok {
w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
return
}
givenUser := sha256.Sum256([]byte(u))
givenPass := sha256.Sum256([]byte(p))
requiredUser := sha256.Sum256([]byte(username))
requiredPass := sha256.Sum256([]byte(password))
if subtle.ConstantTimeCompare(givenUser[:], requiredUser[:]) != 1 ||
subtle.ConstantTimeCompare(givenPass[:], requiredPass[:]) != 1 {
w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
return
}
next.ServeHTTP(w, r)
})
}
}