Enable IdP-initiated SAML flows and simplify authentication

Simplifies SAML authentication by using RelayState to contain the SAML
config ID for both SP-initiated and IdP-initiated flows, removing the
need for the relay_states table and associated token management.

Key changes:
- Enable IdP-initiated flows with AllowIDPInitiated flag
- Use RelayState for SAML config ID instead of secure tokens
- Remove auth_saml_relay_states table and related code
- Maintain InResponseTo validation for SP-initiated flows
- Fix MetadataURL to use entity ID instead of ACS URL

This enables IdP-initiated SAML logins (e.g., from Google Workspace,
Azure Entra ID, Okta) while maintaining security through request ID
validation and assertion replay prevention.

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
This commit is contained in:
Bryan Frimin
2025-11-14 01:41:14 +01:00
parent 80349a3b3b
commit e41997a04d
7 changed files with 107 additions and 325 deletions

View File

@@ -130,6 +130,40 @@ WHERE id = @id
return nil
}
func LoadValidRequestIDsForOrganization(
ctx context.Context,
conn pg.Conn,
organizationID gid.GID,
now time.Time,
) ([]string, error) {
query := `
SELECT id
FROM auth_saml_requests
WHERE organization_id = @organization_id AND expires_at > @now
`
args := pgx.NamedArgs{
"organization_id": organizationID,
"now": now,
}
rows, err := conn.Query(ctx, query, args)
if err != nil {
return nil, fmt.Errorf("cannot query saml_requests: %w", err)
}
requestIDs, err := pgx.CollectRows(rows, func(row pgx.CollectableRow) (string, error) {
var id string
err := row.Scan(&id)
return id, err
})
if err != nil {
return nil, fmt.Errorf("cannot collect request IDs: %w", err)
}
return requestIDs, nil
}
func DeleteExpiredSAMLRequests(ctx context.Context, conn pg.Conn, now time.Time) (int64, error) {
query := `
DELETE FROM auth_saml_requests