Skip to content

Provider-only sign-in mode: storefront and panel login pages, My account, sign-out at the provider - #908

Merged
KrzysztofPajak merged 13 commits into
developfrom
feature/oidc-provider-only-web
Oct 14, 2026
Merged

KrzysztofPajak merged 13 commits into
developfrom
feature/oidc-provider-only-web

Conversation

@KrzysztofPajak

Copy link
Copy Markdown
Member

Resolves no public issue
Type: feature

Issue

With the provider-only sign-in mode (previous pull request in this stack), the storefront and the panels still showed password forms, registration, password recovery and "My account" password/two-factor pages that can no longer be used, and signing out ended only the GrandNode session while the identity provider kept the user signed in.

Second of four stacked pull requests (core → web → plugin → guide); based on the core branch.

Solution

  • Storefront: /login and /register go straight to the identity provider and back to the page asked for (only local return URLs); password recovery goes to /login; registration is possible only through the provider's external registration form; a notice replaces the forms when no provider can sign in (no redirect loops); a signed-in account sent to /login gets a sign-out link instead of a loop through the provider.
  • Panels: Store and Vendor login pages redirect to the provider; the Admin login page redirects unless /admin/login?password=1, which shows the password form for break-glass accounts; a signed-in account without panel access gets a notice and a sign-out link.
  • My account: e-mail read-only, change password and two-factor settings hidden and refused, the OpenID Connect connection cannot be removed (other providers can), account deletion needs no GrandNode password.
  • Sign-out: new optional core interface IExternalSignOutProvider; in ProviderOnly, when the cookie came from a provider sign-in, storefront and panel sign-out redirect to the provider's end-session URL (absolute http(s) only) after the local sign-out; IGrandAuthenticationService.HasOidcSession() (default implementation returns false).
  • Mixed behaves exactly as before.

Breaking changes

IGrandAuthenticationService gains HasOidcSession() with a default implementation. The panel HomeControllers no longer take IGrandAuthenticationService in their constructors. In ProviderOnly, panel sign-out ends on the storefront home page (the post-logout address registered at the provider).

Testing

  1. dotnet test GrandNode.slnx (new tests for the storefront and panel login pages, My account rules and provider sign-out).
  2. With SignInMode=ProviderOnly: /login, /register, /admin/login, /store/login, /vendor/login redirect to /oidc/login; /admin/login?password=1 shows the password form; deactivating the OpenID Connect method shows a notice instead of redirecting.
  3. Sign out after a provider sign-in: the browser passes the provider's end-session endpoint and returns to the store home page; the next sign-in asks the provider for the password. Verified in a real browser with Keycloak 26.8 (it shows its own logout confirmation) and Zitadel v4.19.

@KrzysztofPajak
KrzysztofPajak force-pushed the feature/oidc-provider-only-web branch from 629fc99 to 55ffa9b Compare October 14, 2026 10:39
Base automatically changed from feature/oidc-provider-only-core to develop October 14, 2026 14:28
… instead of a redirect loop through the provider
…e provider connection are managed by the identity provider
… authentication service from the panel home controllers
…login gets a sign-out link instead of a loop through the provider

- Login no longer redirects a registered, signed-in customer to the provider (which signed the same account in again
  and returned to the page that refused it); the page offers the sign-out instead
- the provider sign-in address comes from the first active provider that returns a path
- Cancel on the external registration form goes to the home page (Register would go back to the provider)
- the disable two-factor test now proves the provider-only guard alone redirects
… session), so existing implementations still build
…ns out locally only, never at the identity provider
… also when the store's registration is disabled
@KrzysztofPajak
KrzysztofPajak force-pushed the feature/oidc-provider-only-web branch from f64af00 to 297b569 Compare October 14, 2026 14:30

var redirect = result as RedirectResult;
Assert.IsNotNull(redirect);
Assert.AreEqual("/shop/oidc/login?returnUrl=%2Fshop%2Fstore", redirect.Url);

var redirect = result as RedirectResult;
Assert.IsNotNull(redirect);
Assert.AreEqual("/shop/oidc/login?returnUrl=%2Fshop%2Fadmin", redirect.Url);
Comment on lines +36 to +40
catch (Exception ex)
{
//never keep the customer signed in because the provider could not be asked
logger.LogWarning(ex, "Could not get the sign-out URL of the identity provider");
}
@KrzysztofPajak
KrzysztofPajak merged commit a95b6af into develop Oct 14, 2026
6 checks passed
@KrzysztofPajak
KrzysztofPajak deleted the feature/oidc-provider-only-web branch October 14, 2026 15:26
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.

1 participant