Add login, logout, and forbidden pages with identity provider base class#10
Closed
Add login, logout, and forbidden pages with identity provider base class#10
Conversation
… tests Agent-Logs-Url: https://github.com/webexpress-framework/WebExpress.WebApp/sessions/30e800a4-eb1b-40dd-a6e6-e8364c799d8c Co-authored-by: ReneSchwarzer <31061438+ReneSchwarzer@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Create dedicated logout and access denied pages for user experience
Add login, logout, and forbidden pages with identity provider base class
Apr 14, 2026
ReneSchwarzer
approved these changes
Apr 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Introduces dedicated auth-flow pages and an identity provider abstraction to support consistent login/logout UX and permission-denied handling across WebExpress applications.
New Pages
All three pages use a shared
VisualTreeWebAppLogin— a stripped-down visual tree (header + centered card, no sidebar/breadcrumb) that establishes the common layout convention.PageWebAppLogin— username/password form; delegates toIdentityManager.Login()with validationPageWebAppLogout— callsIdentityManager.Logout()on render, then shows confirmation with link back to loginPageWebAppForbidden— access-denied page for authenticated users lacking permissions; offers a switch-account link to loginHTTP Status Pages
PageStatusWebAppForbidden—[StatusResponse<ResponseForbidden>](HTTP 403)PageStatusWebAppUnauthorized—[StatusResponse<ResponseUnauthorized>](HTTP 401)Both follow the existing
PageStatusWebApppattern.Identity Provider
IdentityProvideris an abstract base class applications can extend:Authenticate(IRequest)is implemented on the base class: parses theAuthorizationheader and dispatches to the appropriate abstract hook based onBasicorBearer/Tokenscheme.Internationalization
Added
enanddekeys for all new UI strings (login form labels/errors, logout confirmation, forbidden message, 401/403 status descriptions).Notes
ControlFormItemInputTextis used for the password field since the framework has no dedicated password input control; a swap toControlFormItemInputPasswordis straightforward once available.SecureStringwrapping inPageWebAppLoginis required byIdentityManager.Login(IRequest, IIdentity, SecureString)— the plain string is unavoidably in memory before wrapping due to how the form system works.Original prompt
A dedicated logout page must be created to provide a clear and consistent user experience when terminating an authenticated session. This page must follow the structural and stylistic conventions established by PageWebAppLogin, including its layout, navigation behavior, and use of standardized WebExpress controls. After performing the logout operation, the page must present a concise confirmation message and offer a direct navigation path back to the login page.
In addition, a separate page must be implemented for situations where a user is authenticated but lacks the required permissions to access the requested resource. This page must also be modeled after PageWebAppLogin and must clearly communicate that access is denied due to insufficient privileges. It must provide contextual guidance, such as offering a link to switch accounts or return to a safe default location within the application.
If necessary, the IdentityProvider must be extended to support these flows, particularly to ensure that logout operations, permission checks, and state transitions are handled consistently across all authentication mechanisms.
Comprehensive unit tests must be added for both pages. These tests must verify correct rendering, proper interaction with the identity system, and the expected behavior when navigating to or from these pages. Tests must also ensure that permission‑related scenarios are handled deterministically and that the logout process reliably clears authentication state.
The following is the prior conversation context from the user's chat exploration (may be truncated):
User: using System.Collections.Generic;
using WebExpress.WebCore.WebIdentity;
using WebExpress.WebCore.WebMessage;
namespace WebExpress.WebApp.WebIdentity
{
///
/// Represents an external identity provider that supplies identities and groups
/// to the WebExpress identity system.
///
public abstract class IdentityProvider : IIdentityProvider
{
///
/// Returns all identities provided by this source.
///
public abstract IEnumerable GetIdentities();
}
Assistant: Um die Anforderungen an die Authentifizierung und den Login-Dialog in der abstrakten Klasse
IdentityProviderumzusetzen, wird die MethodeAuthenticateso implementiert, dass sie den Autorisierungs-Header aus dem Request ausliest und mit der zuvor definierten KlasseRequestAuthorizationparst. Je nach erkanntem Typ (Basic oder Token/Bearer) werden entsprechende abstrakte Validierungsmethoden aufgerufen, die von der ableitenden Klasse implementiert werden müssen, da die konkrete Prüfung von Passwörtern oder Tokens abhängig von der spezifischen Datenquelle ist.Für die Methode
CreateAuthenticationPromptwird eine HTML-basierte Antwort generiert, die ein Login-Formular enthält. Wenn bereits eine Identität übergeben wird, kann deren Name im Formular vorausgefüllt werden. Das Formular verwendet reines Vanilla JavaScript, um die Eingaben zu verarbeiten oder den Vorgang abzubrechen.Hier ist die vollständige und normgerechte Implementierung: