proxy: add JWT request signing support (#19)

- Refactored middleware and request hander logging.
- Request refactored to use context.Context.
- Add helper (based on Alice) to allow middleware chaining.
- Add helper scripts to generate elliptic curve self-signed certificate that can be used to sign JWT.
- Changed LetsEncrypt scripts to use acme instead of certbot.
- Add script to have LetsEncrypt sign an RSA based certificate.
- Add documentation to explain how to verify headers.
- Refactored internal/cryptutil signer's code to expect a valid EC priv key.
- Changed JWT expiries to use default leeway period.
- Update docs and add screenshots.
- Replaced logging handler logic to use context.Context.
- Removed specific XML error handling.
- Refactored handler function signatures to prefer standard go idioms.
This commit is contained in:
Bobby DeSimone 2019-01-22 21:44:22 -08:00 committed by GitHub
parent 98b8c7481f
commit 426e003b03
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
30 changed files with 1711 additions and 588 deletions

View file

@ -1,3 +1,4 @@
// Package middleware provides a standard set of middleware implementations for pomerium.
package middleware // import "github.com/pomerium/pomerium/internal/middleware"
import (
@ -14,8 +15,8 @@ import (
"github.com/pomerium/pomerium/internal/httputil"
)
// SetHeaders ensures that every response includes some basic security headers
func SetHeaders(h http.Handler, securityHeaders map[string]string) http.Handler {
// SetHeadersOld ensures that every response includes some basic security headers
func SetHeadersOld(h http.Handler, securityHeaders map[string]string) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
for key, val := range securityHeaders {
rw.Header().Set(key, val)
@ -24,6 +25,18 @@ func SetHeaders(h http.Handler, securityHeaders map[string]string) http.Handler
})
}
// SetHeaders ensures that every response includes some basic security headers
func SetHeaders(securityHeaders map[string]string) func(next http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
for key, val := range securityHeaders {
rw.Header().Set(key, val)
}
next.ServeHTTP(rw, req)
})
}
}
// WithMethods writes an error response if the method of the request is not included.
func WithMethods(f http.HandlerFunc, methods ...string) http.HandlerFunc {
methodMap := make(map[string]struct{}, len(methods))
@ -116,14 +129,17 @@ func ValidateSignature(f http.HandlerFunc, sharedSecret string) http.HandlerFunc
}
// ValidateHost ensures that each request's host is valid
func ValidateHost(h http.Handler, mux map[string]*http.Handler) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
if _, ok := mux[req.Host]; !ok {
httputil.ErrorResponse(rw, req, "Unknown host to route", http.StatusNotFound)
return
}
h.ServeHTTP(rw, req)
})
func ValidateHost(mux map[string]*http.Handler) func(next http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
if _, ok := mux[req.Host]; !ok {
httputil.ErrorResponse(rw, req, "Unknown host to route", http.StatusNotFound)
return
}
next.ServeHTTP(rw, req)
})
}
}
// RequireHTTPS reroutes a HTTP request to HTTPS