mirror of
https://github.com/pomerium/pomerium.git
synced 2025-06-04 20:03:18 +02:00
proxy: fix invalid session after logout in forward auth mode (#1062)
Currently, authorize service does handle unauthenticated request in forward auth mode, and return status 401. But proxy has not handled the response yet, and always returns 403 for both unauthenticated and unauthorized request. That breaks session handling in forward auth mode. That said, if user was signed out, or for any reason, authorize service return 401 status, proxy does not redirect user to re-signin, but always return 403. To fix it, proxy is changed to handle envoy check response in more details, to distinguish between 401 and 403 status. Thanks to @simbaja for rasing the problem and come up with original fix. Fixes #1014 Fixes #858
This commit is contained in:
parent
7437a4967d
commit
58fb6ea3c4
3 changed files with 67 additions and 34 deletions
|
@ -18,6 +18,11 @@ import (
|
|||
"github.com/pomerium/pomerium/internal/urlutil"
|
||||
)
|
||||
|
||||
type authorizeResponse struct {
|
||||
authorized bool
|
||||
statusCode int32
|
||||
}
|
||||
|
||||
// AuthenticateSession is middleware to enforce a valid authentication
|
||||
// session state is retrieved from the users's request context.
|
||||
func (p *Proxy) AuthenticateSession(next http.Handler) http.Handler {
|
||||
|
@ -45,10 +50,10 @@ func (p *Proxy) redirectToSignin(w http.ResponseWriter, r *http.Request) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (p *Proxy) isAuthorized(w http.ResponseWriter, r *http.Request) (bool, error) {
|
||||
func (p *Proxy) isAuthorized(w http.ResponseWriter, r *http.Request) (*authorizeResponse, error) {
|
||||
tm, err := ptypes.TimestampProto(time.Now())
|
||||
if err != nil {
|
||||
return false, httputil.NewError(http.StatusInternalServerError, fmt.Errorf("error creating protobuf timestamp from current time: %w", err))
|
||||
return nil, httputil.NewError(http.StatusInternalServerError, fmt.Errorf("error creating protobuf timestamp from current time: %w", err))
|
||||
}
|
||||
|
||||
httpAttrs := &envoy_service_auth_v2.AttributeContext_HttpRequest{
|
||||
|
@ -76,18 +81,23 @@ func (p *Proxy) isAuthorized(w http.ResponseWriter, r *http.Request) (bool, erro
|
|||
},
|
||||
})
|
||||
if err != nil {
|
||||
return false, httputil.NewError(http.StatusInternalServerError, err)
|
||||
return nil, httputil.NewError(http.StatusInternalServerError, err)
|
||||
}
|
||||
|
||||
ar := &authorizeResponse{}
|
||||
switch res.HttpResponse.(type) {
|
||||
case *envoy_service_auth_v2.CheckResponse_OkResponse:
|
||||
for _, hdr := range res.GetOkResponse().GetHeaders() {
|
||||
w.Header().Set(hdr.GetHeader().GetKey(), hdr.GetHeader().GetValue())
|
||||
}
|
||||
return true, nil
|
||||
ar.authorized = true
|
||||
ar.statusCode = res.GetStatus().Code
|
||||
case *envoy_service_auth_v2.CheckResponse_DeniedResponse:
|
||||
ar.statusCode = int32(res.GetDeniedResponse().GetStatus().Code)
|
||||
default:
|
||||
return false, nil
|
||||
ar.statusCode = http.StatusInternalServerError
|
||||
}
|
||||
return ar, nil
|
||||
}
|
||||
|
||||
// SetResponseHeaders sets a map of response headers.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue