mirror of
https://github.com/nais/wonderwall.git
synced 2026-05-09 18:06:42 +00:00
fix: create function for externalSessionId add random string generator. fix tests to reflect provider with checkSessionIframe Session management.
This commit is contained in:
@@ -188,7 +188,11 @@ func (ip *identityProviderHandler) Token(w http.ResponseWriter, r *http.Request)
|
||||
idToken.Set("acr", auth.AcrLevel)
|
||||
idToken.Set("iat", time.Now().Unix())
|
||||
idToken.Set("exp", time.Now().Unix()+expires)
|
||||
idToken.Set("sid", sid)
|
||||
if !ip.Provider.OpenIDConfiguration.GetCheckSessionIframe() {
|
||||
idToken.Set("sid", sid)
|
||||
} else {
|
||||
idToken.Set("session_state", sid)
|
||||
}
|
||||
|
||||
signedIdToken, err := ip.signToken(idToken)
|
||||
if err != nil {
|
||||
|
||||
@@ -6,8 +6,7 @@ import (
|
||||
"github.com/go-chi/chi/v5"
|
||||
)
|
||||
|
||||
func IdentityProviderServer() (*httptest.Server, TestProvider) {
|
||||
provider := NewTestProvider()
|
||||
func IdentityProviderServer(provider TestProvider) (*httptest.Server, TestProvider) {
|
||||
handler := newIdentityProviderHandler(provider)
|
||||
router := identityProviderRouter(handler)
|
||||
server := httptest.NewServer(router)
|
||||
|
||||
@@ -31,6 +31,11 @@ func (p TestProvider) PrivateJwkSet() *jwk.Set {
|
||||
return &p.JwksPair.Private
|
||||
}
|
||||
|
||||
func (p TestProvider) WithCheckSessionIframe() TestProvider {
|
||||
p.OpenIDConfiguration.CheckSessionIframe = "https://some-url/checksession"
|
||||
return p
|
||||
}
|
||||
|
||||
func NewTestProvider() TestProvider {
|
||||
jwksPair, err := crypto.NewJwkSet()
|
||||
if err != nil {
|
||||
|
||||
@@ -73,12 +73,8 @@ func (c *Configuration) FetchJwkSet(ctx context.Context) (*jwk.Set, error) {
|
||||
return &jwkSet, nil
|
||||
}
|
||||
|
||||
func (c *Configuration) FetchCheckSessionIframe() bool {
|
||||
if c.CheckSessionIframe == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
func (c *Configuration) GetCheckSessionIframe() bool {
|
||||
return c.CheckSessionIframe != ""
|
||||
}
|
||||
|
||||
func (c *Configuration) SidClaimRequired() bool {
|
||||
|
||||
@@ -123,7 +123,7 @@ func (h *Handler) ExternalSessionId(idToken *openid.IDToken) (string, error) {
|
||||
switch {
|
||||
case openIDconfig.SidClaimRequired():
|
||||
externalSessionID, err = idToken.GetStringClaim("sid")
|
||||
case openIDconfig.FetchCheckSessionIframe():
|
||||
case openIDconfig.GetCheckSessionIframe():
|
||||
externalSessionID, err = idToken.GetStringClaim("session_state")
|
||||
default:
|
||||
externalSessionID = h.GenerateExternalSessionID()
|
||||
|
||||
@@ -44,7 +44,7 @@ func newHandler(provider openid.Provider) *router.Handler {
|
||||
}
|
||||
|
||||
func TestHandler_Login(t *testing.T) {
|
||||
idpserver, idp := mock.IdentityProviderServer()
|
||||
idpserver, idp := mock.IdentityProviderServer(mock.NewTestProvider())
|
||||
h := newHandler(idp)
|
||||
r := router.New(h)
|
||||
|
||||
@@ -100,7 +100,7 @@ func TestHandler_Login(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestHandler_Callback_and_Logout(t *testing.T) {
|
||||
idpserver, idp := mock.IdentityProviderServer()
|
||||
idpserver, idp := mock.IdentityProviderServer(mock.NewTestProvider())
|
||||
|
||||
h := newHandler(idp)
|
||||
r := router.New(h)
|
||||
@@ -195,7 +195,80 @@ func TestHandler_Callback_and_Logout(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestHandler_FrontChannelLogout(t *testing.T) {
|
||||
_, idp := mock.IdentityProviderServer()
|
||||
_, idp := mock.IdentityProviderServer(mock.NewTestProvider())
|
||||
h := newHandler(idp)
|
||||
r := router.New(h)
|
||||
server := httptest.NewServer(r)
|
||||
|
||||
idp.ClientConfiguration.RedirectURI = server.URL + "/oauth2/callback"
|
||||
idp.ClientConfiguration.PostLogoutRedirectURI = server.URL
|
||||
|
||||
jar, err := cookiejar.New(nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
client := server.Client()
|
||||
client.Jar = jar
|
||||
client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
|
||||
return http.ErrUseLastResponse
|
||||
}
|
||||
|
||||
// First, run /oauth2/login to set cookies
|
||||
resp, err := client.Get(server.URL + "/oauth2/login")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, http.StatusTemporaryRedirect, resp.StatusCode)
|
||||
defer resp.Body.Close()
|
||||
|
||||
// Get authorization URL
|
||||
location := resp.Header.Get("location")
|
||||
u, err := url.Parse(location)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Follow redirect to authorize with idporten
|
||||
resp, err = client.Get(u.String())
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, http.StatusTemporaryRedirect, resp.StatusCode)
|
||||
defer resp.Body.Close()
|
||||
|
||||
// Get callback URL after successful auth
|
||||
location = resp.Header.Get("location")
|
||||
callbackURL, err := url.Parse(location)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Follow redirect to callback
|
||||
resp, err = client.Get(callbackURL.String())
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, http.StatusTemporaryRedirect, resp.StatusCode)
|
||||
|
||||
cookies := client.Jar.Cookies(callbackURL)
|
||||
sessionCookie := getCookieFromJar(router.SessionCookieName, cookies)
|
||||
|
||||
assert.NotNil(t, sessionCookie)
|
||||
|
||||
// Trigger front-channel logout
|
||||
ciphertext, err := base64.StdEncoding.DecodeString(sessionCookie.Value)
|
||||
assert.NoError(t, err)
|
||||
|
||||
sid, err := h.Crypter.Decrypt(ciphertext)
|
||||
assert.NoError(t, err)
|
||||
|
||||
frontchannelLogoutURL, err := url.Parse(server.URL)
|
||||
assert.NoError(t, err)
|
||||
|
||||
frontchannelLogoutURL.Path = "/oauth2/logout/frontchannel"
|
||||
|
||||
values := url.Values{}
|
||||
values.Add("sid", string(sid))
|
||||
values.Add("iss", idp.GetOpenIDConfiguration().Issuer)
|
||||
frontchannelLogoutURL.RawQuery = values.Encode()
|
||||
|
||||
resp, err = client.Get(frontchannelLogoutURL.String())
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
defer resp.Body.Close()
|
||||
}
|
||||
|
||||
func TestHandler_FrontChannelLogoutWithCheckSessionIframe(t *testing.T) {
|
||||
_, idp := mock.IdentityProviderServer(mock.NewTestProvider().WithCheckSessionIframe())
|
||||
h := newHandler(idp)
|
||||
r := router.New(h)
|
||||
server := httptest.NewServer(r)
|
||||
|
||||
Reference in New Issue
Block a user