fix(config): wire introspectionURL override and repair dead endpoint overrides (#152)

Issue #152 asks for a manual introspection endpoint because some IdPs
omit introspection_endpoint from discovery. Analysis found the two
documented overrides revocationURL and oidcEndSessionURL were dead
code: the 1b49e13 rebuild dropped their constructor wiring.

Add the IntrospectionURL config field and wire all three overrides.
The overrides apply inside updateMetadataEndpoints, so they survive
every metadata refresh. A manual value always wins over discovery.
The constructor also seeds the live fields, so a failed discovery
does not lose operator configuration.

Manual values skip the poisoned-discovery defences on purpose. They
sit at the same trust tier as providerURL and isValidSecureURL gates
them at config time.

Add issue152_regression_test.go: 8 tests pin precedence, refresh
survival, cold-start seeding, end-to-end introspection over HTTP,
and the validation contract.
This commit is contained in:
2026-08-09 01:59:47 +01:00
parent 78b6f193b3
commit f728f61777
7 changed files with 651 additions and 27 deletions
+14 -6
View File
@@ -49,12 +49,16 @@ type Config struct {
RoleClaimName string `json:"roleClaimName,omitempty"`
CookieDomain string `json:"cookieDomain"`
OIDCEndSessionURL string `json:"oidcEndSessionURL"`
Scopes []string `json:"scopes"`
AllowedRolesAndGroups []string `json:"allowedRolesAndGroups"`
ExcludedURLs []string `json:"excludedURLs"`
AllowedUserDomains []string `json:"allowedUserDomains"`
AllowedUsers []string `json:"allowedUsers"`
Headers []TemplatedHeader `json:"headers"`
// IntrospectionURL overrides the RFC 7662 token introspection endpoint.
// Set it when the IdP omits introspection_endpoint from discovery. It
// takes precedence over the discovered value.
IntrospectionURL string `json:"introspectionURL"`
Scopes []string `json:"scopes"`
AllowedRolesAndGroups []string `json:"allowedRolesAndGroups"`
ExcludedURLs []string `json:"excludedURLs"`
AllowedUserDomains []string `json:"allowedUserDomains"`
AllowedUsers []string `json:"allowedUsers"`
Headers []TemplatedHeader `json:"headers"`
// AllowedClaims extends the built-in claims whitelist that header value
// templates may emit. Add the exact claim name (e.g. "employee_id") to allow
// {{.Claims.employee_id}} / {{get .Claims "employee_id"}}. Applies to both
@@ -483,6 +487,10 @@ func (c *Config) Validate() error {
if c.OIDCEndSessionURL != "" && !isValidSecureURL(c.OIDCEndSessionURL) {
return fmt.Errorf("oidcEndSessionURL must be a valid HTTPS URL")
}
// Validate introspection URL if set
if c.IntrospectionURL != "" && !isValidSecureURL(c.IntrospectionURL) {
return fmt.Errorf("introspectionURL must be a valid HTTPS URL")
}
// Validate post-logout redirect URI if set
if c.PostLogoutRedirectURI != "" && c.PostLogoutRedirectURI != "/" {