pomerium/integration/authentication_test.go
Kenneth Jenkins e0ac870442
integration: fix multi-stateless configuration (#4845)
Commit 08c186a contains a bug in the integration configuration template,
preventing the multi-stateless cluster from actually setting the
DEBUG_FORCE_AUTHENTICATE_FLOW environment variable. As a result this
cluster was not exercising the stateless authentication flow.

Fix the template so that this variable is applied as intended.

Add an integration test case to verify that the intended authentication
flow is in use: for the stateful flow, different routes should share the
same underlying session, but for the stateless flow, different routes
should receive different sessions.
2023-12-08 09:12:15 -08:00

77 lines
2.3 KiB
Go

package main
import (
"context"
"net/http"
"net/url"
"testing"
"time"
"github.com/go-jose/go-jose/v3/jwt"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/pomerium/pomerium/integration/flows"
)
func TestRouteSessions(t *testing.T) {
ctx, clearTimeout := context.WithTimeout(context.Background(), time.Second*30)
defer clearTimeout()
client := getClient(t)
// Sign in to access one route.
url1 := mustParseURL("https://httpdetails.localhost.pomerium.io/by-domain")
res, err := flows.Authenticate(ctx, client, url1, flows.WithEmail("user1@dogs.test"))
require.NoError(t, err)
require.Equal(t, http.StatusOK, res.StatusCode, "expected OK for httpdetails")
// Now request a different route. This should not require signing in again,
// but will redirect through the authenticate service if using the
// stateless authentication flow.
client.CheckRedirect = nil
url2 := mustParseURL("https://restricted-httpdetails.localhost.pomerium.io/by-domain")
req, _ := http.NewRequestWithContext(ctx, http.MethodGet, url2.String(), nil)
res, err = client.Do(req)
require.NoError(t, err)
require.Equal(t, http.StatusOK, res.StatusCode, "expected OK for restricted-httpdetails")
// Now examine the session cookies saved for each route.
claims1 := getSessionCookieJWTClaims(t, client, url1)
claims2 := getSessionCookieJWTClaims(t, client, url2)
if AuthenticateFlow == "stateless" {
// Under the stateless authenticate flow, each route should have its
// own session.
assert.NotEqual(t, claims1.ID, claims2.ID)
} else {
// Under the stateful authenticate flow, the two routes should share
// the same session.
assert.Equal(t, claims1.ID, claims2.ID)
}
}
func getSessionCookieJWTClaims(t *testing.T, client *http.Client, u *url.URL) *jwt.Claims {
t.Helper()
cookie := getSessionCookie(t, client, u)
token, err := jwt.ParseSigned(cookie.Value)
require.NoError(t, err)
var claims jwt.Claims
err = token.UnsafeClaimsWithoutVerification(&claims)
require.NoError(t, err)
return &claims
}
func getSessionCookie(t *testing.T, client *http.Client, u *url.URL) *http.Cookie {
t.Helper()
for _, c := range client.Jar.Cookies(u) {
if c.Name == "_pomerium" {
return c
}
}
t.Fatalf("no session cookie found for URL %q", u.String())
return nil
}