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

@ -110,7 +110,10 @@ func TestNewReverseProxyHandler(t *testing.T) {
proxyHandler := NewReverseProxy(proxyURL)
opts := defaultOptions
handle := NewReverseProxyHandler(opts, proxyHandler, "name")
handle, err := NewReverseProxyHandler(opts, proxyHandler, "from", "to")
if err != nil {
t.Errorf("got %q", err)
}
frontend := httptest.NewServer(handle)
@ -152,7 +155,8 @@ func TestOptions_Validate(t *testing.T) {
invalidCookieSecret.CookieSecret = "OromP1gurwGWjQPYb1nNgSxtbVB5NnLzX6z5WOKr0Yw^"
shortCookieLength := testOptions()
shortCookieLength.CookieSecret = "gN3xnvfsAwfCXxnJorGLKUG4l2wC8sS8nfLMhcStPg=="
invalidSignKey := testOptions()
invalidSignKey.SigningKey = "OromP1gurwGWjQPYb1nNgSxtbVB5NnLzX6z5WOKr0Yw^"
badSharedKey := testOptions()
badSharedKey.SharedKey = ""
@ -162,7 +166,6 @@ func TestOptions_Validate(t *testing.T) {
wantErr bool
}{
{"good - minimum options", good, false},
{"nil options", &Options{}, true},
{"from route", badFromRoute, true},
{"to route", badToRoute, true},
@ -172,6 +175,7 @@ func TestOptions_Validate(t *testing.T) {
{"invalid cookie secret", invalidCookieSecret, true},
{"short cookie secret", shortCookieLength, true},
{"no shared secret", badSharedKey, true},
{"invalid signing key", invalidSignKey, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@ -187,6 +191,8 @@ func TestNew(t *testing.T) {
good := testOptions()
shortCookieLength := testOptions()
shortCookieLength.CookieSecret = "gN3xnvfsAwfCXxnJorGLKUG4l2wC8sS8nfLMhcStPg=="
badRoutedProxy := testOptions()
badRoutedProxy.SigningKey = "YmFkIGtleQo="
tests := []struct {
name string
@ -197,9 +203,10 @@ func TestNew(t *testing.T) {
wantErr bool
}{
{"good - minimum options", good, nil, true, 1, false},
{"bad - empty options", &Options{}, nil, false, 0, true},
{"bad - nil options", nil, nil, false, 0, true},
{"bad - short secret/validate sanity check", shortCookieLength, nil, false, 0, true},
{"empty options", &Options{}, nil, false, 0, true},
{"nil options", nil, nil, false, 0, true},
{"short secret/validate sanity check", shortCookieLength, nil, false, 0, true},
{"invalid ec key, valid base64 though", badRoutedProxy, nil, false, 0, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {