Skip to content

OIDC: option to send the login page straight to the provider - #19

Merged
mastacontrola merged 1 commit into
mainfrom
oidc-auto-redirect
Aug 18, 2026
Merged

OIDC: option to send the login page straight to the provider#19
mastacontrola merged 1 commit into
mainfrom
oidc-auto-redirect

Conversation

@mastacontrola

Copy link
Copy Markdown
Member

Closes #17. Consumes the LOGIN_PAGE_REDIRECT seam from
FOGProject/fogproject#1175, and depends on #18 (single logout) for its schema
ordering.

The ask

For an install where every account lives at the identity provider, FOG's
username and password box is a dead end — it cannot accept those credentials, so
the only thing to do on that page is click past it. opAutoRedirect, per
provider, sends an anonymous visitor straight to the provider instead.

It is also the most dangerous setting in this plugin, and most of what follows is
containment rather than feature.

Off by default, everywhere a default can be stated

The appended ALTER (existing installs), createSql() (fresh ones), and the
create page. An install that upgraded into this switched on would find its login
form replaced by a redirect nobody asked for — and the only URL that still shows
the form is one nobody has been told about yet.

Two flagged providers refuse and render the form

As argued in the issue. The login page cannot redirect to both, and silently
picking one — lowest id, first row, whatever — hides a misconfiguration on the
single page an admin is least able to debug, while sending everybody to a
provider half of them may not have an account at. Refusing is a working login for
everyone and visibly not what was asked for.

The complaint names both providers in the error log and not on the page. This
code runs for a visitor who has not signed in, and "this server has two
misconfigured identity providers" is not something to tell one.

Two loops that had to be closed first

Both previously landed on management/index.php — precisely the page this
feature redirects:

Path Was Now
Provider refuses the sign-in (_fail()) index.php → straight back out; infinite loop if the provider is down, unreadable flash if not login.php — one error message on a page that stays put
Log out with auto-redirect on, single logout off index.php → provider → SSO session still alive → silently signed back in login.php — a fallback only, so a real provider-logout URL still wins

"Log out" that leaves you logged in is worse than no logout at all.

The escape hatch

Core's, and pinned there. index.php offers LOGIN_PAGE_REDIRECT only when
FOG_LOCAL_LOGIN is undefined, so management/login.php never reaches this
plugin's listener at all. Nothing here can change that — which is the whole
reason it lives in core: a plugin that is misconfigured, half-installed or
throwing cannot take that page down with it, because it is not asked anything.

The management page prints that URL next to the checkbox. Not decoration: an
admin who ticks this box without knowing login.php exists has one expired
certificate between themselves and being locked out of their own server, and at
that point the URL is not something they could guess.

Verification

tests/oidc-auto-redirect.test.php — 20 checks, 21/21 mutations caught:
default flipping to on, a step inserted rather than appended, several flagged
providers silently resolved to one, the ambiguity reaching the page instead of
the log, a relative start URL (core's seam drops it, so the setting would
silently do nothing at all), both loop regressions, and the fallback overriding a
real provider logout.

One mutation survived the first draft and is worth recording: the escape-hatch
assertion searched the whole page for the URL, and the page prints it twice
so removing it from the autoRedirect label, the only place an admin reads it,
still passed. Now scoped to that label.

sh tests/run-all.sh6 passed, 0 failed.

Not yet exercised end to end against the lab Keycloak, same as #18.

Follow-up

User docs for both settings — and for management/login.php — belong in
FOGProject/fog-docs and are worth writing now that the pair is complete.

🤖 Generated with Claude Code

https://claude.ai/code/session_017aBSWrDArXHTpKWkkN27LR

Closes #17. Consumes the LOGIN_PAGE_REDIRECT seam from fogproject#1175.

For an install where every account lives at the identity provider, FOG's
username and password box is a dead end -- it cannot accept those
credentials, so the only thing to do on that page is click past it.
`opAutoRedirect`, per provider, sends an anonymous visitor straight to the
provider instead.

It is also the most dangerous setting in this plugin, and most of what is
below is containment rather than feature.

## Off by default, in every place a default can be stated

An appended ALTER (existing installs), createSql() (fresh ones), and the
create page. An install that upgraded into this switched on would find its
login form replaced by a redirect nobody asked for, and the only URL that
still shows the form is one nobody has been told about.

## Two flagged providers refuse and render the form

The login page cannot redirect to both. Silently picking one -- lowest id,
first row, whatever -- hides a misconfiguration on the single page an admin
is least able to debug, while sending everybody to a provider half of them
may not have an account at. Refusing is a working login for everyone and
visibly not what was asked for.

The complaint names both providers in the error log and NOT on the page.
This code runs for a visitor who has not signed in, and "this server has
two misconfigured identity providers" is not something to tell one.

## Two loops that had to be closed first

Both used to land on management/index.php, which is precisely the page this
feature redirects:

- A refused sign-in. `_fail()` now returns to management/login.php, so a
  provider that is down produces one error message rather than an infinite
  redirect -- and the flash message is attached to a page that stays put
  instead of one that immediately hops again.
- Logging out with automatic redirect on but single logout off. Core's
  default landing spot would bounce the person who just signed out back to
  a provider whose SSO session is still alive and sign them silently back
  in. "Log out" that leaves you logged in is worse than no logout at all,
  so the USER_LOGGING_OUT listener falls back to management/login.php --
  only as a fallback, so a real provider-logout URL still wins.

## The escape hatch

Core's, and pinned there: index.php offers LOGIN_PAGE_REDIRECT only when
FOG_LOCAL_LOGIN is undefined, so management/login.php never reaches this
plugin's listener at all. Nothing here can change that, which is the whole
reason it lives in core -- a plugin that is misconfigured, half-installed
or throwing cannot take the page down with it, because it is not asked
anything.

The management page prints that URL next to the checkbox. Not decoration:
an admin who ticks this box without knowing login.php exists has one
expired certificate between themselves and being locked out of their own
server, and at that point the URL is not something they could guess.

## Verification

tests/oidc-auto-redirect.test.php, 20 checks, 21/21 mutations caught --
including the default flipping to on, a step inserted rather than appended,
several flagged providers being silently resolved to one, the ambiguity
reaching the page instead of the log, a relative start URL (which core's
seam drops, so the setting would silently do nothing), both loop
regressions, and the fallback overriding a real provider logout.

One of those mutations survived the first draft and is worth recording: the
escape-hatch assertion searched the whole page for the URL, and the page
prints it twice -- so removing it from the autoRedirect label, which is the
only place an admin reads it, still passed. Now scoped to that label.

sh tests/run-all.sh -> 6 passed, 0 failed.

Not exercised end to end against the lab Keycloak yet.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017aBSWrDArXHTpKWkkN27LR
@mastacontrola
mastacontrola merged commit d259151 into main Aug 18, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OIDC: option to send the login page straight to the provider

1 participant