mirror of
https://github.com/go-gitea/gitea.git
synced 2026-04-13 22:29:59 +02:00
Backport #36085 by @eliroca When authentication is handled externally by a reverse proxy SSO provider, users can be redirected to an external logout URL or relative path defined on the reverse proxy. Co-authored-by: Elisei Roca <eroca@suse.de> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
parent
fc5e0ec877
commit
7a7376dfc8
@ -461,6 +461,11 @@ INTERNAL_TOKEN =
|
||||
;; Name of cookie used to store authentication information.
|
||||
;COOKIE_REMEMBER_NAME = gitea_incredible
|
||||
;;
|
||||
;; URL or path that Gitea should redirect users to *after* performing its own logout.
|
||||
;; Use this, if needed, when authentication is handled by a reverse proxy or SSO.
|
||||
;; For example: "/my-sso/logout?return=/my-sso/home"
|
||||
;REVERSE_PROXY_LOGOUT_REDIRECT =
|
||||
;;
|
||||
;; Reverse proxy authentication header name of user name, email, and full name
|
||||
;REVERSE_PROXY_AUTHENTICATION_USER = X-WEBAUTH-USER
|
||||
;REVERSE_PROXY_AUTHENTICATION_EMAIL = X-WEBAUTH-EMAIL
|
||||
|
||||
@ -31,6 +31,7 @@ var (
|
||||
ReverseProxyAuthEmail string
|
||||
ReverseProxyAuthFullName string
|
||||
ReverseProxyLimit int
|
||||
ReverseProxyLogoutRedirect string
|
||||
ReverseProxyTrustedProxies []string
|
||||
MinPasswordLength int
|
||||
ImportLocalPaths bool
|
||||
@ -124,6 +125,7 @@ func loadSecurityFrom(rootCfg ConfigProvider) {
|
||||
ReverseProxyAuthFullName = sec.Key("REVERSE_PROXY_AUTHENTICATION_FULL_NAME").MustString("X-WEBAUTH-FULLNAME")
|
||||
|
||||
ReverseProxyLimit = sec.Key("REVERSE_PROXY_LIMIT").MustInt(1)
|
||||
ReverseProxyLogoutRedirect = sec.Key("REVERSE_PROXY_LOGOUT_REDIRECT").String()
|
||||
ReverseProxyTrustedProxies = sec.Key("REVERSE_PROXY_TRUSTED_PROXIES").Strings(",")
|
||||
if len(ReverseProxyTrustedProxies) == 0 {
|
||||
ReverseProxyTrustedProxies = []string{"127.0.0.0/8", "::1/128"}
|
||||
|
||||
@ -493,12 +493,17 @@ func SignOut(ctx *context.Context) {
|
||||
}
|
||||
|
||||
func buildSignOutRedirectURL(ctx *context.Context) string {
|
||||
// TODO: can also support REVERSE_PROXY_AUTHENTICATION logout URL in the future
|
||||
if ctx.Doer != nil && ctx.Doer.LoginType == auth.OAuth2 {
|
||||
if s := buildOIDCEndSessionURL(ctx, ctx.Doer); s != "" {
|
||||
return s
|
||||
}
|
||||
}
|
||||
|
||||
// The assumption is: if reverse proxy auth is enabled, then the users should only sign-in via reverse proxy auth.
|
||||
// TODO: in the future, if we need to distinguish different sign-in methods, we need to save the sign-in method in session and check here
|
||||
if setting.Service.EnableReverseProxyAuth && setting.ReverseProxyLogoutRedirect != "" {
|
||||
return setting.ReverseProxyLogoutRedirect
|
||||
}
|
||||
return setting.AppSubURL + "/"
|
||||
}
|
||||
|
||||
|
||||
@ -7,6 +7,7 @@ import (
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/test"
|
||||
"code.gitea.io/gitea/tests"
|
||||
|
||||
@ -16,13 +17,29 @@ import (
|
||||
func TestSignOut(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
session := loginUser(t, "user2")
|
||||
t.Run("NormalLogout", func(t *testing.T) {
|
||||
session := loginUser(t, "user2")
|
||||
|
||||
req := NewRequest(t, "GET", "/user/logout")
|
||||
resp := session.MakeRequest(t, req, http.StatusSeeOther)
|
||||
assert.Equal(t, "/", test.RedirectURL(resp))
|
||||
req := NewRequest(t, "GET", "/user/logout")
|
||||
resp := session.MakeRequest(t, req, http.StatusSeeOther)
|
||||
assert.Equal(t, "/", resp.Header().Get("Location"))
|
||||
|
||||
// try to view a private repo, should fail
|
||||
req = NewRequest(t, "GET", "/user2/repo2")
|
||||
session.MakeRequest(t, req, http.StatusNotFound)
|
||||
// logged out, try to view a private repo, should fail
|
||||
req = NewRequest(t, "GET", "/user2/repo2")
|
||||
session.MakeRequest(t, req, http.StatusNotFound)
|
||||
})
|
||||
|
||||
t.Run("ReverseProxyLogoutRedirect", func(t *testing.T) {
|
||||
defer test.MockVariableValue(&setting.Service.EnableReverseProxyAuth, true)()
|
||||
defer test.MockVariableValue(&setting.ReverseProxyLogoutRedirect, "/my-sso/logout?return_to=/my-sso/home")()
|
||||
|
||||
session := loginUser(t, "user2")
|
||||
req := NewRequest(t, "GET", "/user/logout")
|
||||
resp := session.MakeRequest(t, req, http.StatusSeeOther)
|
||||
assert.Equal(t, "/my-sso/logout?return_to=/my-sso/home", resp.Header().Get("Location"))
|
||||
|
||||
// logged out, try to view a private repo, should fail
|
||||
req = NewRequest(t, "GET", "/user2/repo2")
|
||||
session.MakeRequest(t, req, http.StatusNotFound)
|
||||
})
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user