authenticate: fix internal url with webauthn (#3194) (#3195)

Co-authored-by: Caleb Doxsey <cdoxsey@pomerium.com>
This commit is contained in:
backport-actions-token[bot] 2022-03-28 07:03:41 -06:00 committed by GitHub
parent e55b581f61
commit 95df8c5447
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 47 additions and 31 deletions

View file

@ -731,20 +731,26 @@ func (a *Authenticate) getWebauthnState(ctx context.Context) (*webauthn.State, e
return nil, err return nil, err
} }
internalAuthenticateURL, err := a.options.Load().GetInternalAuthenticateURL()
if err != nil {
return nil, err
}
pomeriumDomains, err := a.options.Load().GetAllRouteableHTTPDomains() pomeriumDomains, err := a.options.Load().GetAllRouteableHTTPDomains()
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &webauthn.State{ return &webauthn.State{
AuthenticateURL: authenticateURL, AuthenticateURL: authenticateURL,
SharedKey: state.sharedKey, InternalAuthenticateURL: internalAuthenticateURL,
Client: state.dataBrokerClient, SharedKey: state.sharedKey,
PomeriumDomains: pomeriumDomains, Client: state.dataBrokerClient,
Session: s, PomeriumDomains: pomeriumDomains,
SessionState: ss, Session: s,
SessionStore: state.sessionStore, SessionState: ss,
RelyingParty: state.webauthnRelyingParty, SessionStore: state.sessionStore,
RelyingParty: state.webauthnRelyingParty,
}, nil }, nil
} }

View file

@ -47,14 +47,15 @@ var (
// State is the state needed by the Handler to handle requests. // State is the state needed by the Handler to handle requests.
type State struct { type State struct {
AuthenticateURL *url.URL AuthenticateURL *url.URL
Client databroker.DataBrokerServiceClient InternalAuthenticateURL *url.URL
PomeriumDomains []string Client databroker.DataBrokerServiceClient
RelyingParty *webauthn.RelyingParty PomeriumDomains []string
Session *session.Session RelyingParty *webauthn.RelyingParty
SessionState *sessions.State Session *session.Session
SessionStore sessions.SessionStore SessionState *sessions.State
SharedKey []byte SessionStore sessions.SessionStore
SharedKey []byte
} }
// A StateProvider provides state for the handler. // A StateProvider provides state for the handler.
@ -122,7 +123,10 @@ func (h *Handler) handle(w http.ResponseWriter, r *http.Request) error {
return err return err
} }
err = middleware.ValidateRequestURL(r, s.SharedKey) err = middleware.ValidateRequestURL(
urlutil.GetExternalRequest(s.InternalAuthenticateURL, s.AuthenticateURL, r),
s.SharedKey,
)
if err != nil { if err != nil {
return err return err
} }

View file

@ -46,18 +46,5 @@ func (a *Authenticate) getExternalRequest(r *http.Request) *http.Request {
return r return r
} }
// if we're not using a different internal URL there's nothing to do return urlutil.GetExternalRequest(internalURL, externalURL, r)
if externalURL.String() == internalURL.String() {
return r
}
// replace the internal host with the external host
er := r.Clone(r.Context())
if er.URL.Host == internalURL.Host {
er.URL.Host = externalURL.Host
}
if er.Host == internalURL.Host {
er.Host = externalURL.Host
}
return er
} }

View file

@ -141,3 +141,22 @@ func Join(elements ...string) string {
} }
return builder.String() return builder.String()
} }
// GetExternalRequest modifies a request so that it appears to be for an external URL instead of
// an internal URL.
func GetExternalRequest(internalURL, externalURL *url.URL, r *http.Request) *http.Request {
// if we're not using a different internal URL there's nothing to do
if externalURL.String() == internalURL.String() {
return r
}
// replace the internal host with the external host
er := r.Clone(r.Context())
if er.URL.Host == internalURL.Host {
er.URL.Host = externalURL.Host
}
if er.Host == internalURL.Host {
er.Host = externalURL.Host
}
return er
}