Skip to content

Commit

Permalink
remove forward auth (#3628)
Browse files Browse the repository at this point in the history
  • Loading branch information
calebdoxsey committed Nov 23, 2022
1 parent ba07afc commit fa26587
Show file tree
Hide file tree
Showing 68 changed files with 304 additions and 5,074 deletions.
33 changes: 0 additions & 33 deletions .devcontainer/Dockerfile

This file was deleted.

21 changes: 0 additions & 21 deletions .devcontainer/devcontainer.json

This file was deleted.

32 changes: 0 additions & 32 deletions .devcontainer/envs/nginx.yaml

This file was deleted.

50 changes: 0 additions & 50 deletions .devcontainer/envs/traefik.yaml

This file was deleted.

21 changes: 0 additions & 21 deletions .devcontainer/readme.md

This file was deleted.

2 changes: 1 addition & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ jobs:
go-version: [1.19.x]
node-version: [16.x]
platform: [ubuntu-latest]
deployment: [kubernetes, multi, nginx, single, traefik]
deployment: [kubernetes, multi, single]
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/setup-go@c4a742cab115ed795e34d4513e2cf7d472deb55f
Expand Down
5 changes: 0 additions & 5 deletions authenticate/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,11 +201,6 @@ func (a *Authenticate) SignIn(w http.ResponseWriter, r *http.Request) error {
jwtAudience = append(jwtAudience, callbackURL.Host)
}

// add an additional claim for the forward-auth host, if set
if fwdAuth := r.FormValue(urlutil.QueryForwardAuth); fwdAuth != "" {
jwtAudience = append(jwtAudience, fwdAuth)
}

s, err := a.getSessionFromCtx(ctx)
if err != nil {
state.sessionStore.ClearSession(w, r)
Expand Down
1 change: 0 additions & 1 deletion authenticate/handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,6 @@ func TestAuthenticate_SignIn(t *testing.T) {
{"good with callback uri set", "https", "corp.example.example", map[string]string{urlutil.QueryCallbackURI: "https://some.example/", urlutil.QueryRedirectURI: "https://dst.some.example/"}, &mstore.Store{Session: &sessions.State{}}, identity.MockProvider{}, &mock.Encoder{}, http.StatusFound},
{"bad callback uri set", "https", "corp.example.example", map[string]string{urlutil.QueryCallbackURI: "^", urlutil.QueryRedirectURI: "https://dst.some.example/"}, &mstore.Store{Session: &sessions.State{}}, identity.MockProvider{}, &mock.Encoder{}, http.StatusBadRequest},
{"good programmatic request", "https", "corp.example.example", map[string]string{urlutil.QueryIsProgrammatic: "true", urlutil.QueryRedirectURI: "https://dst.some.example/"}, &mstore.Store{Session: &sessions.State{}}, identity.MockProvider{}, &mock.Encoder{}, http.StatusFound},
{"good additional audience", "https", "corp.example.example", map[string]string{urlutil.QueryForwardAuth: "x.y.z", urlutil.QueryRedirectURI: "https://dst.some.example/"}, &mstore.Store{Session: &sessions.State{}}, identity.MockProvider{}, &mock.Encoder{}, http.StatusFound},
}
for _, tt := range tests {
tt := tt
Expand Down
78 changes: 34 additions & 44 deletions authorize/check_response.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,25 +32,24 @@ func (a *Authorize) handleResult(
in *envoy_service_auth_v3.CheckRequest,
request *evaluator.Request,
result *evaluator.Result,
isForwardAuthVerify bool,
) (*envoy_service_auth_v3.CheckResponse, error) {
// when the user is unauthenticated it means they haven't
// logged in yet, so redirect to authenticate
if result.Allow.Reasons.Has(criteria.ReasonUserUnauthenticated) ||
result.Deny.Reasons.Has(criteria.ReasonUserUnauthenticated) {
return a.requireLoginResponse(ctx, in, request, isForwardAuthVerify)
return a.requireLoginResponse(ctx, in, request)
}

// when the user's device is unauthenticated it means they haven't
// registered a webauthn device yet, so redirect to the webauthn flow
if result.Allow.Reasons.Has(criteria.ReasonDeviceUnauthenticated) ||
result.Deny.Reasons.Has(criteria.ReasonDeviceUnauthenticated) {
return a.requireWebAuthnResponse(ctx, in, request, result, isForwardAuthVerify)
return a.requireWebAuthnResponse(ctx, in, request, result)
}

// if there's a deny, the result is denied using the deny reasons.
if result.Deny.Value {
return a.handleResultDenied(ctx, in, request, result, isForwardAuthVerify, result.Deny.Reasons)
return a.handleResultDenied(ctx, in, request, result, result.Deny.Reasons)
}

// if there's an allow, the result is allowed.
Expand All @@ -59,7 +58,7 @@ func (a *Authorize) handleResult(
}

// otherwise, the result is denied using the allow reasons.
return a.handleResultDenied(ctx, in, request, result, isForwardAuthVerify, result.Allow.Reasons)
return a.handleResultDenied(ctx, in, request, result, result.Allow.Reasons)
}

func (a *Authorize) handleResultAllowed(
Expand All @@ -75,15 +74,14 @@ func (a *Authorize) handleResultDenied(
in *envoy_service_auth_v3.CheckRequest,
request *evaluator.Request,
result *evaluator.Result,
isForwardAuthVerify bool,
reasons criteria.Reasons,
) (*envoy_service_auth_v3.CheckResponse, error) {
denyStatusCode := int32(http.StatusForbidden)
denyStatusText := http.StatusText(http.StatusForbidden)

switch {
case reasons.Has(criteria.ReasonDeviceUnauthenticated):
return a.requireWebAuthnResponse(ctx, in, request, result, isForwardAuthVerify)
return a.requireWebAuthnResponse(ctx, in, request, result)
case reasons.Has(criteria.ReasonDeviceUnauthorized):
denyStatusCode = httputil.StatusDeviceUnauthorized
denyStatusText = httputil.DetailsText(httputil.StatusDeviceUnauthorized)
Expand Down Expand Up @@ -122,42 +120,36 @@ func (a *Authorize) deniedResponse(
in *envoy_service_auth_v3.CheckRequest,
code int32, reason string, headers map[string]string,
) (*envoy_service_auth_v3.CheckResponse, error) {
respBody := []byte(reason)
respHeader := []*envoy_config_core_v3.HeaderValueOption{}

forwardAuthURL, _ := a.currentOptions.Load().GetForwardAuthURL()
if forwardAuthURL == nil {
// create a http response writer recorder
w := httptest.NewRecorder()
r := getHTTPRequestFromCheckRequest(in)

// build the user info / debug endpoint
debugEndpoint, _ := a.userInfoEndpointURL(in) // if there's an error, we just wont display it

// run the request through our go error handler
httpErr := httputil.HTTPError{
Status: int(code),
Err: errors.New(reason),
DebugURL: debugEndpoint,
RequestID: requestid.FromContext(ctx),
BrandingOptions: a.currentOptions.Load().BrandingOptions,
}
httpErr.ErrorResponse(ctx, w, r)

// transpose the go http response writer into a envoy response
resp := w.Result()
defer resp.Body.Close()
var err error
respBody, err = io.ReadAll(resp.Body)
if err != nil {
log.Error(ctx).Err(err).Msg("error executing error template")
return nil, err
}
// convert go headers to envoy headers
respHeader = append(respHeader, toEnvoyHeaders(resp.Header)...)
} else {
respHeader = append(respHeader, mkHeader("Content-Type", "text/plain", false))
// create a http response writer recorder
w := httptest.NewRecorder()
r := getHTTPRequestFromCheckRequest(in)

// build the user info / debug endpoint
debugEndpoint, _ := a.userInfoEndpointURL(in) // if there's an error, we just wont display it

// run the request through our go error handler
httpErr := httputil.HTTPError{
Status: int(code),
Err: errors.New(reason),
DebugURL: debugEndpoint,
RequestID: requestid.FromContext(ctx),
BrandingOptions: a.currentOptions.Load().BrandingOptions,
}
httpErr.ErrorResponse(ctx, w, r)

// transpose the go http response writer into a envoy response
resp := w.Result()
defer resp.Body.Close()

respBody, err := io.ReadAll(resp.Body)
if err != nil {
log.Error(ctx).Err(err).Msg("error executing error template")
return nil, err
}
// convert go headers to envoy headers
respHeader = append(respHeader, toEnvoyHeaders(resp.Header)...)

// add any additional headers
for k, v := range headers {
Expand All @@ -182,7 +174,6 @@ func (a *Authorize) requireLoginResponse(
ctx context.Context,
in *envoy_service_auth_v3.CheckRequest,
request *evaluator.Request,
isForwardAuthVerify bool,
) (*envoy_service_auth_v3.CheckResponse, error) {
opts := a.currentOptions.Load()
state := a.state.Load()
Expand All @@ -191,7 +182,7 @@ func (a *Authorize) requireLoginResponse(
return nil, err
}

if !a.shouldRedirect(in) || isForwardAuthVerify {
if !a.shouldRedirect(in) {
return a.deniedResponse(ctx, in, http.StatusUnauthorized, http.StatusText(http.StatusUnauthorized), nil)
}

Expand Down Expand Up @@ -223,7 +214,6 @@ func (a *Authorize) requireWebAuthnResponse(
in *envoy_service_auth_v3.CheckRequest,
request *evaluator.Request,
result *evaluator.Result,
isForwardAuthVerify bool,
) (*envoy_service_auth_v3.CheckResponse, error) {
opts := a.currentOptions.Load()
state := a.state.Load()
Expand All @@ -232,7 +222,7 @@ func (a *Authorize) requireWebAuthnResponse(
return nil, err
}

if !a.shouldRedirect(in) || isForwardAuthVerify {
if !a.shouldRedirect(in) {
return a.deniedResponse(ctx, in, http.StatusUnauthorized, http.StatusText(http.StatusUnauthorized), nil)
}

Expand Down
15 changes: 5 additions & 10 deletions authorize/check_response_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ func TestAuthorize_handleResult(t *testing.T) {
&evaluator.Request{},
&evaluator.Result{
Allow: evaluator.NewRuleResult(false, criteria.ReasonUserUnauthenticated),
},
false)
})
assert.NoError(t, err)
assert.Equal(t, 302, int(res.GetDeniedResponse().GetStatus().GetCode()))

Expand All @@ -47,8 +46,7 @@ func TestAuthorize_handleResult(t *testing.T) {
&evaluator.Request{},
&evaluator.Result{
Deny: evaluator.NewRuleResult(false, criteria.ReasonUserUnauthenticated),
},
false)
})
assert.NoError(t, err)
assert.Equal(t, 302, int(res.GetDeniedResponse().GetStatus().GetCode()))
})
Expand Down Expand Up @@ -191,8 +189,7 @@ func TestRequireLogin(t *testing.T) {
t.Run("accept empty", func(t *testing.T) {
res, err := a.requireLoginResponse(context.Background(),
&envoy_service_auth_v3.CheckRequest{},
&evaluator.Request{},
false)
&evaluator.Request{})
require.NoError(t, err)
assert.Equal(t, http.StatusFound, int(res.GetDeniedResponse().GetStatus().GetCode()))
})
Expand All @@ -209,8 +206,7 @@ func TestRequireLogin(t *testing.T) {
},
},
},
&evaluator.Request{},
false)
&evaluator.Request{})
require.NoError(t, err)
assert.Equal(t, http.StatusFound, int(res.GetDeniedResponse().GetStatus().GetCode()))
})
Expand All @@ -227,8 +223,7 @@ func TestRequireLogin(t *testing.T) {
},
},
},
&evaluator.Request{},
false)
&evaluator.Request{})
require.NoError(t, err)
assert.Equal(t, http.StatusUnauthorized, int(res.GetDeniedResponse().GetStatus().GetCode()))
})
Expand Down
Loading

0 comments on commit fa26587

Please sign in to comment.