Merge 356f8cac26 into e27921ee80
This commit is contained in:
commit
e71be73642
|
|
@ -38,6 +38,20 @@ X-Auth-Request-Redirect: https://my-oidc-provider/sign_out_page
|
|||
|
||||
BEWARE that the domain you want to redirect to (`my-oidc-provider.example.com` in the example) must be added to the [`--whitelist-domain`](../configuration/overview) configuration option otherwise the redirect will be ignored. Make sure to include the actual domain and port (if needed) and not the URL (e.g "localhost:8081" instead of "http://localhost:8081").
|
||||
|
||||
ID Token can be injected in the redirect url by using `{id_token}` placeholder. For example to redirect to `https://my-oidc-provider.example.com/sign_out_page?id_token_hint={id_token}&post_logout_redirect_uri=https://my-app.example.com`;
|
||||
|
||||
```
|
||||
/oauth2/sign_out?rd=https%3A%2F%2Fmy-oidc-provider.example.com%2Fsign_out_page%3Fid_token_hint%3D%7Bid_token%7D%26post_logout_redirect_uri%3Dhttps%3A%2F%2Fmy-app.example.com
|
||||
```
|
||||
|
||||
or alternatively in the header:
|
||||
|
||||
```
|
||||
GET /oauth2/sign_out HTTP/1.1
|
||||
X-Auth-Request-Redirect: https://my-oidc-provider.example.com/sign_out_page?id_token_hint={id_token}&post_logout_redirect_uri=https://my-app.example.com
|
||||
...
|
||||
```
|
||||
|
||||
### Auth
|
||||
|
||||
This endpoint returns 202 Accepted response or a 401 Unauthorized response.
|
||||
|
|
|
|||
|
|
@ -54,6 +54,8 @@ const (
|
|||
authOnlyPath = "/auth"
|
||||
userInfoPath = "/userinfo"
|
||||
staticPathPrefix = "/static/"
|
||||
|
||||
idTokenPlaceholder = "{id_token}"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -752,6 +754,15 @@ func (p *OAuthProxy) SignOut(rw http.ResponseWriter, req *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
if strings.Contains(redirect, idTokenPlaceholder) {
|
||||
session, err := p.getAuthenticatedSession(rw, req)
|
||||
if err != nil {
|
||||
logger.Errorf("error getting authenticated session during SignOut, won't replace id_token placeholder in redirect URL: %v", err)
|
||||
} else {
|
||||
redirect = strings.ReplaceAll(redirect, idTokenPlaceholder, session.IDToken)
|
||||
}
|
||||
}
|
||||
|
||||
p.backendLogout(rw, req)
|
||||
|
||||
http.Redirect(rw, req, redirect, http.StatusFound)
|
||||
|
|
@ -773,7 +784,7 @@ func (p *OAuthProxy) backendLogout(rw http.ResponseWriter, req *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
backendLogoutURL := strings.ReplaceAll(providerData.BackendLogoutURL, "{id_token}", session.IDToken)
|
||||
backendLogoutURL := strings.ReplaceAll(providerData.BackendLogoutURL, idTokenPlaceholder, session.IDToken)
|
||||
// security exception because URL is dynamic ({id_token} replacement) but
|
||||
// base is not end-user provided but comes from configuration somewhat secure
|
||||
resp, err := http.Get(backendLogoutURL) // #nosec G107
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/coreos/go-oidc/v3/oidc"
|
||||
middlewareapi "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/middleware"
|
||||
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
|
||||
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/sessions"
|
||||
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/authentication/hmacauth"
|
||||
|
|
@ -3531,3 +3532,49 @@ func TestGetOAuthRedirectURI(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIdTokenPlaceholderInSignOut(t *testing.T) {
|
||||
opts := baseTestOptions()
|
||||
opts.WhitelistDomains = []string{"my-oidc-provider.example.com"}
|
||||
|
||||
err := validation.Validate(opts)
|
||||
assert.NoError(t, err)
|
||||
|
||||
const emailAddress = "john.doe@example.com"
|
||||
const userName = "9fcab5c9b889a557"
|
||||
created := time.Now()
|
||||
|
||||
session := &sessions.SessionState{
|
||||
User: userName,
|
||||
Groups: []string{"a", "b"},
|
||||
Email: emailAddress,
|
||||
IDToken: "eYjjjjjj.vvvv.ddd",
|
||||
AccessToken: "oauth_token",
|
||||
CreatedAt: &created,
|
||||
}
|
||||
|
||||
proxy, err := NewOAuthProxy(opts, func(email string) bool {
|
||||
return true
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Save the required session
|
||||
rw := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("GET", "/", nil)
|
||||
err = proxy.sessionStore.Save(rw, req, session)
|
||||
assert.NoError(t, err)
|
||||
|
||||
rw = httptest.NewRecorder()
|
||||
|
||||
rdUrl := url.QueryEscape("https://my-oidc-provider.example.com/sign_out_page?id_token_hint={id_token}&post_logout_redirect_uri=https://my-app.example.com/")
|
||||
req, _ = http.NewRequest("GET", "/oauth2/sign_out?rd="+rdUrl, nil)
|
||||
req = middlewareapi.AddRequestScope(req, &middlewareapi.RequestScope{
|
||||
RequestID: "11111111-2222-4333-8444-555555555555",
|
||||
Session: session,
|
||||
})
|
||||
|
||||
proxy.SignOut(rw, req)
|
||||
newLocation := rw.Header().Values("Location")[0]
|
||||
|
||||
assert.Equal(t, "https://idp.com/endsession?id_token_hint=eYjjjjjj.vvvv.ddd&post_logout_redirect_uri=http://myapp.com", newLocation)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue