diff --git a/endpoints/publicProxy/providerGithub.go b/endpoints/publicProxy/providerGithub.go index 2682c68f..d89a97ed 100644 --- a/endpoints/publicProxy/providerGithub.go +++ b/endpoints/publicProxy/providerGithub.go @@ -217,7 +217,7 @@ func (c *githubConfigurer) configure() error { fmt.Sprintf("https://api.github.com/applications/%s/token", c.githubCfg.ClientId), strings.NewReader(fmt.Sprintf(`{"access_token":"%s"}`, accessToken))) if err != nil { - logrus.Errorf("error creating token delete request for '%v': %v", claims.Email, err) + logrus.Errorf("error creating access token delete request for '%v': %v", claims.Email, err) proxyUi.WriteUnauthorized(w) return } @@ -227,16 +227,16 @@ func (c *githubConfigurer) configure() error { resp, err := http.DefaultClient.Do(req) if err != nil { - logrus.Errorf("error invoking token delete request for '%v': %v", claims.Email, err) + logrus.Errorf("error invoking access token delete request for '%v': %v", claims.Email, err) proxyUi.WriteUnauthorized(w) return } defer resp.Body.Close() if resp.StatusCode == http.StatusNoContent { - logrus.Infof("revoked github token for '%v'", claims.Email) + logrus.Infof("revoked github access token for '%v'", claims.Email) } else { - logrus.Errorf("token revocation failed with status: %v", resp.StatusCode) + logrus.Errorf("access token revocation failed with status: %v", resp.StatusCode) proxyUi.WriteUnauthorized(w) return } diff --git a/endpoints/publicProxy/providerGoogle.go b/endpoints/publicProxy/providerGoogle.go index 510a7d86..c3ff39e8 100644 --- a/endpoints/publicProxy/providerGoogle.go +++ b/endpoints/publicProxy/providerGoogle.go @@ -200,12 +200,12 @@ func (c *googleConfigurer) configure() error { if resp.StatusCode == http.StatusOK { logrus.Infof("revoked google token for '%v'", claims.Email) } else { - logrus.Errorf("token revocation failed with status: %v", resp.StatusCode) + logrus.Errorf("access token revocation failed with status: %v", resp.StatusCode) proxyUi.WriteUnauthorized(w) return } } else { - logrus.Errorf("unable to revoke token for '%v': %v", claims.Email, err) + logrus.Errorf("unable to revoke access token for '%v': %v", claims.Email, err) proxyUi.WriteUnauthorized(w) return } diff --git a/endpoints/publicProxy/providerOidc.go b/endpoints/publicProxy/providerOidc.go index 550a35d7..fb2ec17a 100644 --- a/endpoints/publicProxy/providerOidc.go +++ b/endpoints/publicProxy/providerOidc.go @@ -226,6 +226,62 @@ func (c *oidcConfigurer) configure() error { } http.Handle(fmt.Sprintf("/%v/auth/callback", c.oidcCfg.Name), rp.CodeExchangeHandler(rp.UserinfoCallback(login), provider)) + logout := func(w http.ResponseWriter, r *http.Request) { + cookie, err := r.Cookie(c.cfg.CookieName) + if err == nil { + tkn, err := jwt.ParseWithClaims(cookie.Value, &zrokClaims{}, func(t *jwt.Token) (interface{}, error) { + return signingKey, nil + }) + if err == nil { + claims := tkn.Claims.(*zrokClaims) + if claims.Provider == c.oidcCfg.Name { + accessToken, err := decryptToken(claims.AccessToken, encryptionKey) + if err == nil { + if err := rp.RevokeToken(context.Background(), provider, accessToken, "access_token"); err == nil { + logrus.Infof("revoked access token for '%v'", claims.Email) + } else { + logrus.Errorf("access token revocation failed: %v", err) + proxyUi.WriteUnauthorized(w) + return + } + } else { + logrus.Errorf("unable to decrypt access token for '%v': %v", claims.Email, err) + proxyUi.WriteUnauthorized(w) + return + } + } else { + logrus.Errorf("expected provider name '%v' got '%v'", c.oidcCfg.Name, claims.Email) + proxyUi.WriteUnauthorized(w) + return + } + } else { + logrus.Errorf("invalid jwt; unable to parse: %v", err) + proxyUi.WriteUnauthorized(w) + return + } + } else { + logrus.Errorf("error getting cookie '%v': %v", c.cfg.CookieName, err) + proxyUi.WriteUnauthorized(w) + return + } + + http.SetCookie(w, &http.Cookie{ + Name: c.cfg.CookieName, + Value: "", + MaxAge: -1, + Domain: c.cfg.CookieDomain, + Path: "/", + HttpOnly: true, + }) + + redirectURL := r.URL.Query().Get("redirect_url") + if redirectURL == "" { + redirectURL = fmt.Sprintf("%s/%s/login", c.cfg.EndpointUrl, c.oidcCfg.Name) + } + http.Redirect(w, r, redirectURL, http.StatusFound) + } + http.HandleFunc(fmt.Sprintf("/%v/logout", c.oidcCfg.Name), logout) + logrus.Infof("configured oidc provider at '/%v'", c.oidcCfg.Name) return nil