mirror of
https://github.com/openziti/zrok.git
synced 2024-12-23 07:09:12 +01:00
fixed redirect to respect intended route, added additional logging around token swapping
This commit is contained in:
parent
4cf8b7d7c6
commit
4be9089cfe
@ -67,7 +67,7 @@ func configureGithubOauth(cfg *OauthConfig, tls bool) error {
|
|||||||
|
|
||||||
type IntermediateJWT struct {
|
type IntermediateJWT struct {
|
||||||
State string `json:"state"`
|
State string `json:"state"`
|
||||||
Share string `json:"share"`
|
Host string `json:"host"`
|
||||||
AuthorizationCheckInterval string `json:"authorizationCheckInterval"`
|
AuthorizationCheckInterval string `json:"authorizationCheckInterval"`
|
||||||
jwt.RegisteredClaims
|
jwt.RegisteredClaims
|
||||||
}
|
}
|
||||||
@ -81,11 +81,15 @@ func configureGithubOauth(cfg *OauthConfig, tls bool) error {
|
|||||||
|
|
||||||
authHandlerWithQueryState := func(party rp.RelyingParty) http.HandlerFunc {
|
authHandlerWithQueryState := func(party rp.RelyingParty) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
host, err := url.QueryUnescape(r.URL.Query().Get("targethost"))
|
||||||
|
if err != nil {
|
||||||
|
logrus.Errorf("Unable to unescape target host: %v", err)
|
||||||
|
}
|
||||||
rp.AuthURLHandler(func() string {
|
rp.AuthURLHandler(func() string {
|
||||||
id := uuid.New().String()
|
id := uuid.New().String()
|
||||||
t := jwt.NewWithClaims(jwt.SigningMethodHS256, IntermediateJWT{
|
t := jwt.NewWithClaims(jwt.SigningMethodHS256, IntermediateJWT{
|
||||||
id,
|
id,
|
||||||
r.URL.Query().Get("share"),
|
host,
|
||||||
r.URL.Query().Get("checkInterval"),
|
r.URL.Query().Get("checkInterval"),
|
||||||
jwt.RegisteredClaims{
|
jwt.RegisteredClaims{
|
||||||
ExpiresAt: jwt.NewNumericDate(time.Now().Add(24 * time.Hour)),
|
ExpiresAt: jwt.NewNumericDate(time.Now().Add(24 * time.Hour)),
|
||||||
@ -120,19 +124,21 @@ func configureGithubOauth(cfg *OauthConfig, tls bool) error {
|
|||||||
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", tokens.AccessToken))
|
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", tokens.AccessToken))
|
||||||
resp, err := http.DefaultClient.Do(req)
|
resp, err := http.DefaultClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Error("Get: " + err.Error() + "\n")
|
logrus.Error("Error getting user info from github: " + err.Error() + "\n")
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
response, err := io.ReadAll(resp.Body)
|
response, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
logrus.Errorf("Error reading response body: %v", err)
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
rDat := []githubUserResp{}
|
rDat := []githubUserResp{}
|
||||||
err = json.Unmarshal(response, &rDat)
|
err = json.Unmarshal(response, &rDat)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
logrus.Errorf("Error unmarshalling google oauth response: %v", err)
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -162,7 +168,7 @@ func configureGithubOauth(cfg *OauthConfig, tls bool) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SetZrokCookie(w, primaryEmail, tokens.AccessToken, "github", authCheckInterval, key)
|
SetZrokCookie(w, primaryEmail, tokens.AccessToken, "github", authCheckInterval, key)
|
||||||
http.Redirect(w, r, fmt.Sprintf("%s://%s.%s:8080", scheme, token.Claims.(*IntermediateJWT).Share, cfg.RedirectUrl), http.StatusFound)
|
http.Redirect(w, r, fmt.Sprintf("%s://%s", scheme, token.Claims.(*IntermediateJWT).Host), http.StatusFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
http.Handle(callbackPath, rp.CodeExchangeHandler(getEmail, relyingParty))
|
http.Handle(callbackPath, rp.CodeExchangeHandler(getEmail, relyingParty))
|
||||||
|
@ -68,7 +68,7 @@ func configureGoogleOauth(cfg *OauthConfig, tls bool) error {
|
|||||||
|
|
||||||
type IntermediateJWT struct {
|
type IntermediateJWT struct {
|
||||||
State string `json:"state"`
|
State string `json:"state"`
|
||||||
Share string `json:"share"`
|
Host string `json:"host"`
|
||||||
AuthorizationCheckInterval string `json:"authorizationCheckInterval"`
|
AuthorizationCheckInterval string `json:"authorizationCheckInterval"`
|
||||||
jwt.RegisteredClaims
|
jwt.RegisteredClaims
|
||||||
}
|
}
|
||||||
@ -79,11 +79,15 @@ func configureGoogleOauth(cfg *OauthConfig, tls bool) error {
|
|||||||
|
|
||||||
authHandlerWithQueryState := func(party rp.RelyingParty) http.HandlerFunc {
|
authHandlerWithQueryState := func(party rp.RelyingParty) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
host, err := url.QueryUnescape(r.URL.Query().Get("targethost"))
|
||||||
|
if err != nil {
|
||||||
|
logrus.Errorf("Unable to unescape target host: %v", err)
|
||||||
|
}
|
||||||
rp.AuthURLHandler(func() string {
|
rp.AuthURLHandler(func() string {
|
||||||
id := uuid.New().String()
|
id := uuid.New().String()
|
||||||
t := jwt.NewWithClaims(jwt.SigningMethodHS256, IntermediateJWT{
|
t := jwt.NewWithClaims(jwt.SigningMethodHS256, IntermediateJWT{
|
||||||
id,
|
id,
|
||||||
r.URL.Query().Get("share"),
|
host,
|
||||||
r.URL.Query().Get("checkInterval"),
|
r.URL.Query().Get("checkInterval"),
|
||||||
jwt.RegisteredClaims{
|
jwt.RegisteredClaims{
|
||||||
ExpiresAt: jwt.NewNumericDate(time.Now().Add(24 * time.Hour)),
|
ExpiresAt: jwt.NewNumericDate(time.Now().Add(24 * time.Hour)),
|
||||||
@ -107,19 +111,21 @@ func configureGoogleOauth(cfg *OauthConfig, tls bool) error {
|
|||||||
getEmail := func(w http.ResponseWriter, r *http.Request, tokens *oidc.Tokens[*oidc.IDTokenClaims], state string, rp rp.RelyingParty) {
|
getEmail := func(w http.ResponseWriter, r *http.Request, tokens *oidc.Tokens[*oidc.IDTokenClaims], state string, rp rp.RelyingParty) {
|
||||||
resp, err := http.Get("https://www.googleapis.com/oauth2/v2/userinfo?access_token=" + url.QueryEscape(tokens.AccessToken))
|
resp, err := http.Get("https://www.googleapis.com/oauth2/v2/userinfo?access_token=" + url.QueryEscape(tokens.AccessToken))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Error("Get: " + err.Error() + "\n")
|
logrus.Error("Error getting user info from google: " + err.Error() + "\n")
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
response, err := io.ReadAll(resp.Body)
|
response, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
logrus.Errorf("Error reading response body: %v", err)
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
rDat := googleOauthEmailResp{}
|
rDat := googleOauthEmailResp{}
|
||||||
err = json.Unmarshal(response, &rDat)
|
err = json.Unmarshal(response, &rDat)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
logrus.Errorf("Error unmarshalling google oauth response: %v", err)
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -141,7 +147,7 @@ func configureGoogleOauth(cfg *OauthConfig, tls bool) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SetZrokCookie(w, rDat.Email, tokens.AccessToken, "google", authCheckInterval, key)
|
SetZrokCookie(w, rDat.Email, tokens.AccessToken, "google", authCheckInterval, key)
|
||||||
http.Redirect(w, r, fmt.Sprintf("%s://%s.%s:8080", scheme, token.Claims.(*IntermediateJWT).Share, cfg.RedirectUrl), http.StatusFound)
|
http.Redirect(w, r, fmt.Sprintf("%s://%s", scheme, token.Claims.(*IntermediateJWT).Host), http.StatusFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
http.Handle(callbackPath, rp.CodeExchangeHandler(getEmail, relyingParty))
|
http.Handle(callbackPath, rp.CodeExchangeHandler(getEmail, relyingParty))
|
||||||
|
@ -208,10 +208,12 @@ func authHandler(handler http.Handler, realm string, pcfg *Config, ctx ziti.Cont
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
target := fmt.Sprintf("%s%s", r.Host, r.URL.Path)
|
||||||
|
|
||||||
cookie, err := r.Cookie("zrok-access")
|
cookie, err := r.Cookie("zrok-access")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Errorf("Unable to get access cookie: %v", err)
|
logrus.Errorf("Unable to get access cookie: %v", err)
|
||||||
http.Redirect(w, r, fmt.Sprintf("http://%s.%s:%d/%s/login?share=%s&checkInterval=%s", shrToken, pcfg.HostMatch, pcfg.Oauth.Port, provider.(string), shrToken, authCheckInterval.String()), http.StatusFound)
|
http.Redirect(w, r, fmt.Sprintf("http://%s.%s:%d/%s/login?targethost=%s&checkInterval=%s", shrToken, pcfg.HostMatch, pcfg.Oauth.Port, provider.(string), url.QueryEscape(target), authCheckInterval.String()), http.StatusFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
tkn, err := jwt.ParseWithClaims(cookie.Value, &ZrokClaims{}, func(t *jwt.Token) (interface{}, error) {
|
tkn, err := jwt.ParseWithClaims(cookie.Value, &ZrokClaims{}, func(t *jwt.Token) (interface{}, error) {
|
||||||
@ -222,18 +224,18 @@ func authHandler(handler http.Handler, realm string, pcfg *Config, ctx ziti.Cont
|
|||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Errorf("Unable to parse JWT: %v", err)
|
logrus.Errorf("Unable to parse JWT: %v", err)
|
||||||
http.Redirect(w, r, fmt.Sprintf("http://%s.%s:%d/%s/login?share=%s&checkInterval=%s", shrToken, pcfg.HostMatch, pcfg.Oauth.Port, provider.(string), shrToken, authCheckInterval.String()), http.StatusFound)
|
http.Redirect(w, r, fmt.Sprintf("http://%s.%s:%d/%s/login?targethost=%s&checkInterval=%s", shrToken, pcfg.HostMatch, pcfg.Oauth.Port, provider.(string), url.QueryEscape(target), authCheckInterval.String()), http.StatusFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
claims := tkn.Claims.(*ZrokClaims)
|
claims := tkn.Claims.(*ZrokClaims)
|
||||||
if claims.Provider != provider {
|
if claims.Provider != provider {
|
||||||
logrus.Error("Provider mismatch. Redoing auth flow")
|
logrus.Error("Provider mismatch. Redoing auth flow")
|
||||||
http.Redirect(w, r, fmt.Sprintf("http://%s.%s:%d/%s/login?share=%s&checkInterval=%s", shrToken, pcfg.HostMatch, pcfg.Oauth.Port, provider.(string), shrToken, authCheckInterval.String()), http.StatusFound)
|
http.Redirect(w, r, fmt.Sprintf("http://%s.%s:%d/%s/login?targethost=%s&checkInterval=%s", shrToken, pcfg.HostMatch, pcfg.Oauth.Port, provider.(string), url.QueryEscape(target), authCheckInterval.String()), http.StatusFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if claims.AuthorizationCheckInterval != authCheckInterval {
|
if claims.AuthorizationCheckInterval != authCheckInterval {
|
||||||
logrus.Error("Authorization check interval mismatch. Redoing auth flow")
|
logrus.Error("Authorization check interval mismatch. Redoing auth flow")
|
||||||
http.Redirect(w, r, fmt.Sprintf("http://%s.%s:%d/%s/login?share=%s&checkInterval=%s", shrToken, pcfg.HostMatch, pcfg.Oauth.Port, provider.(string), shrToken, authCheckInterval.String()), http.StatusFound)
|
http.Redirect(w, r, fmt.Sprintf("http://%s.%s:%d/%s/login?targethost=%s&checkInterval=%s", shrToken, pcfg.HostMatch, pcfg.Oauth.Port, provider.(string), url.QueryEscape(target), authCheckInterval.String()), http.StatusFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if validDomains, found := oauthCfg.(map[string]interface{})["email_domains"]; found {
|
if validDomains, found := oauthCfg.(map[string]interface{})["email_domains"]; found {
|
||||||
|
Loading…
Reference in New Issue
Block a user