Auth

TsgcHTMLAuth: sessioni lato server, stato di login e protezione CSRF per un’applicazione sgcHTML, in Delphi, C++ Builder e .NET.

TsgcHTMLAuth

Un componente non visuale che gestisce il cookie di sessione, l’utente connesso e il token CSRF di ogni richiesta. Assegna un archivio di sessioni, gestisci OnAuthenticate per verificare la password, imposta la proprietà Auth dell’engine HTMX e contrassegna le route con RequireLogin. Fa parte di sgcHTML, che si vende indipendentemente come pack di componenti autonomo.

Classe del componente

TsgcHTMLAuth con TsgcHTMLSessionStore_Memory, TsgcHTMLSessionStore_File e TsgcHTMLSession (unit sgcHTML_Auth e sgcHTML_Session)

Renderizza

Nessun markup: cookie di sessione, token CSRF e reindirizzamenti al login

Famiglia

Autenticazione

Linguaggi

Delphi, C++ Builder, .NET

Crea un archivio, crea l’Auth, proteggi una route

Assegna un archivio di sessioni, gestisci OnAuthenticate, imposta Auth sull’engine e contrassegna le route da proteggere. Da quel momento l’engine legge la sessione di ogni richiesta, verifica il token CSRF e reindirizza gli utenti anonimi a LoginPath.

uses
  sgcHTML_Session, sgcHTML_Auth, sgcHTMX_Router, sgcHTMX_Engine_Server;

// oHTMX is a TsgcHTMX_Engine_Server, oRouter is a TsgcHTMX_Router
var
  oStore: TsgcHTMLSessionStore_Memory;
  oAuth: TsgcHTMLAuth;
  oRoute: TsgcHTMX_Route;
begin
  oStore := TsgcHTMLSessionStore_Memory.Create(Self);
  oStore.SweepInterval := 60;

  oAuth := TsgcHTMLAuth.Create(Self);
  oAuth.SessionStore := oStore;
  oAuth.IdleTimeout := 1800;       // seconds without a request
  oAuth.AbsoluteTimeout := 43200;  // seconds since sign-in
  oAuth.LoginRateLimit.MaxAttempts := 5;
  oAuth.OnAuthenticate := AuthAuthenticate;
  oHTMX.Auth := oAuth;

  // only a signed-in user reaches /orders
  oRoute := oRouter.Routes.Add;
  oRoute.Path := '/orders';
  oRoute.RequireLogin := True;
  oRoute.OnRoute := OrdersRoute;

  // only a session with one of these roles reaches /admin
  oRoute := oRouter.Routes.Add;
  oRoute.Path := '/admin';
  oRoute.RequireRoles := 'admin,manager';
  oRoute.OnRoute := AdminRoute;
end;

procedure TForm1.AuthAuthenticate(Sender: TObject;
  const aUser, aPassword: string; var aAccept: Boolean;
  var aUserID, aDisplayName: string; const aRoles: TStrings);
begin
  // LoadPasswordHash reads the value stored when the user was created
  aAccept := sgcHTMLPasswordVerify(aPassword, LoadPasswordHash(aUser));
  if aAccept then
  begin
    aUserID := aUser;
    aDisplayName := aUser;
    aRoles.Add('admin');
  end;
end;

// when you create a user, store this hash, never the password
vHash := sgcHTMLPasswordHash('secret');
// includes: sgcHTML_Session.hpp, sgcHTML_Auth.hpp, sgcHTMX_Router.hpp, sgcHTMX_Engine_Server.hpp
// oHTMX is a TsgcHTMX_Engine_Server, oRouter is a TsgcHTMX_Router

TsgcHTMLSessionStore_Memory *oStore = new TsgcHTMLSessionStore_Memory(this);
oStore->SweepInterval = 60;

TsgcHTMLAuth *oAuth = new TsgcHTMLAuth(this);
oAuth->SessionStore = oStore;
oAuth->IdleTimeout = 1800;       // seconds without a request
oAuth->AbsoluteTimeout = 43200;  // seconds since sign-in
oAuth->LoginRateLimit->MaxAttempts = 5;
oAuth->OnAuthenticate = AuthAuthenticate;
oHTMX->Auth = oAuth;

// only a signed-in user reaches /orders
TsgcHTMX_Route *oRoute = oRouter->Routes->Add();
oRoute->Path = "/orders";
oRoute->RequireLogin = true;
oRoute->OnRoute = OrdersRoute;

// only a session with one of these roles reaches /admin
oRoute = oRouter->Routes->Add();
oRoute->Path = "/admin";
oRoute->RequireRoles = "admin,manager";
oRoute->OnRoute = AdminRoute;

void __fastcall TForm1::AuthAuthenticate(TObject *Sender,
  const UnicodeString aUser, const UnicodeString aPassword, bool &aAccept,
  UnicodeString &aUserID, UnicodeString &aDisplayName, TStrings *const aRoles)
{
  // LoadPasswordHash reads the value stored when the user was created
  aAccept = sgcHTMLPasswordVerify(aPassword, LoadPasswordHash(aUser));
  if (aAccept)
  {
    aUserID = aUser;
    aDisplayName = aUser;
    aRoles->Add("admin");
  }
}

// when you create a user, store this hash, never the password
String hash = sgcHTMLPasswordHash("secret");
using esegece.sgcWebSockets;

// htmx is a TsgcHTMX_Engine_Server, router is a TsgcHTMX_Router
var store = new TsgcHTMLSessionStore_Memory();
store.SweepInterval = 60;

var auth = new TsgcHTMLAuth();
auth.SessionStore = store;
auth.IdleTimeout = 1800;       // seconds without a request
auth.AbsoluteTimeout = 43200;  // seconds since sign-in
auth.LoginRateLimit.MaxAttempts = 5;
auth.OnAuthenticate += AuthAuthenticate;
htmx.Auth = auth;

// only a signed-in user reaches /orders
var route = router.Routes.Add();
route.Path = "/orders";
route.RequireLogin = true;
route.OnRoute += OrdersRoute;

// only a session with one of these roles reaches /admin
route = router.Routes.Add();
route.Path = "/admin";
route.RequireRoles = "admin,manager";
route.OnRoute += AdminRoute;

void AuthAuthenticate(object sender, string aUser, string aPassword,
    ref bool aAccept, ref string aUserID, ref string aDisplayName,
    List<string> aRoles)
{
    // LoadPasswordHash reads the value stored when the user was created
    aAccept = sgcHTMLAuthHelpers.sgcHTMLPasswordVerify(aPassword, LoadPasswordHash(aUser));
    if (aAccept)
    {
        aUserID = aUser;
        aDisplayName = aUser;
        aRoles.Add("admin");
    }
}

// when you create a user, store this hash, never the password
string hash = sgcHTMLAuthHelpers.sgcHTMLPasswordHash("secret");

Proprietà e metodi principali

I membri che utilizzerai più spesso.

CookieName (predefinito sgcsid), CookiePath e CookieDomain definiscono il cookie. CookieSecure e CookieHttpOnly sono True per impostazione predefinita e CookieSameSite è hssLax; hssStrict e hssNone sono gli altri valori, e hssNone aggiunge sempre Secure.

Timeout

IdleTimeout (1800 secondi) termina una sessione rimasta inutilizzata, AbsoluteTimeout (43200 secondi) la termina trascorso quel tempo dal login, qualunque sia l’attività. 0 disattiva ciascuno dei due controlli. CurrentSession convalida entrambi e aggiorna la sessione a ogni richiesta.

Token CSRF

CSRFProtection è attivo per impostazione predefinita. Ogni sessione riceve un token casuale: IssueCSRF(session) lo restituisce e ValidateCSRF(session, token) lo confronta in tempo costante. L’engine legge il token dall’header CSRFHeaderName (X-CSRF-Token) o dal campo CSRFFieldName (csrf_token) e risponde 403 a una richiesta che modifica lo stato e ne è priva.

CSRF con htmx

Una pagina renderizzata per una sessione autenticata contiene <meta name="csrf-token"> e <meta name="csrf-header"> nel proprio head, e lo script htmx incluso invia il token in quell’header a ogni richiesta che non sia GET, HEAD o OPTIONS. hx-post e hx-delete non richiedono markup aggiuntivo.

Ricordami

RememberMeDays (0 significa disattivato, al massimo 3650) lo attiva e RememberCookieName assegna il nome al cookie (sgcrem). Quando una richiesta non ha una sessione valida ma ha un token valido, OnLoadUser ricarica l’utente, viene emessa una nuova sessione e il token viene ruotato. L’archivio conserva solo un hash del verificatore.

Limite di frequenza dei login

LoginRateLimit è un TsgcHTMLAuthRateLimit_Options. I login falliti vengono contati per IP del client e per nome utente entro WindowSeconds (300); al raggiungimento di MaxAttempts (5) quell’IP o utente viene bloccato per LockoutSeconds (900), e durante il blocco OnAuthenticate non viene chiamato. MaxAttempts = 0 disattiva il limite e IsLoginLocked(ip, user) segnala un blocco.

Password

sgcHTMLPasswordHash(password, iterations) restituisce pbkdf2-sha256$iterations$salt$hash con un salt casuale di 16 byte e 210000 iterazioni per impostazione predefinita. sgcHTMLPasswordVerify(password, hash) verifica una password in tempo costante e restituisce False per un hash malformato.

Archivi di sessione

TsgcHTMLSessionStore_Memory conserva le sessioni nel processo, con SweepInterval per una pulizia in background; mantieni i suoi IdleTimeout e AbsoluteTimeout uguali a quelli dell’Auth. TsgcHTMLSessionStore_File scrive un file JSON per sessione in Folder, così più processi possono condividerlo, e riscrive un file al massimo ogni TouchInterval secondi (60). Entrambi sono thread-safe.

La sessione

TsgcHTMLSession contiene ID, UserID, DisplayName, Roles, Values liberi (name=value), CSRFToken, CreatedAt, LastSeen, RemoteIP e UserAgentHash, oltre a HasRole. Una route la legge come TsgcHTMXRequest.Session, nil quando è anonima. Gli archivi restituiscono copie, quindi chiama SessionStore.Put per conservare una modifica.

Accesso e uscita

Authenticate applica il limite di frequenza e scatena OnAuthenticate. SignIn crea sempre un nuovo id di sessione, elimina il vecchio ed emette un nuovo token CSRF, il che difende dal session fixation. SignOut termina una sessione e SignOutEverywhere(userID) termina ogni sessione e ogni token ricordami di un utente. Fuori dall’engine, chiama tu stesso CurrentSession(cookieHeader, remoteIP, userAgent, setCookies), come fa la demo Admin CRUD.

Protezione delle route

Contrassegna una TsgcHTMX_Route con RequireLogin oppure RequireRoles (separati da virgole, basta una corrispondenza). Una richiesta anonima viene reindirizzata a LoginPath?next= con un 302, oppure riceve 401 più HX-Redirect quando l’ha inviata htmx; una sessione priva del ruolo riceve 403. L’engine risponde anche al POST verso LoginPath e LogoutPath, poi passa a AfterLoginPath.

Connessioni WebSocket

Un messaggio viene eseguito con la sessione dei cookie inviati nell’handshake WebSocket, purché quell’handshake provenga dalla stessa origine; qualsiasi altro messaggio è anonimo, e un messaggio negato non riceve risposta. TsgcHTMX_Engine_Server.MessageSession(aConnection) restituisce la sessione associata a una connessione, per un host che risponde direttamente a OnHTMXMessage, e il chiamante la libera.

Continua a esplorare

Guida in lineaRiferimento API completo e guida all’uso per questo componente.
Guida a sessioni e autenticazioneCookie, CSRF, protezione delle route, ricordami e limite di frequenza dei login, passo dopo passo.
Tutti i componenti sgcHTMLEsplora la matrice completa delle funzionalità di oltre 80 componenti.
Scarica la Prova GratuitaLa prova di 30 giorni include i progetti demo 60.HTML, tra cui 02.AdminCRUD, che accede tramite TsgcHTMLAuth.
PrezziLicenze Single, Team e Site con codice sorgente completo.
La scelta più conveniente: All-AccessTutti i prodotti eSeGeCe, con Supporto Premium incluso, a partire da €1,059/anno.
Vedi i prezzi All-Access

Pronto a Iniziare?

Scarica la versione di prova gratuita e inizia a creare interfacce web in Delphi, C++ Builder e .NET.