Kitto.Auth
Defines the base authenticator and related classes and services. Authenticators allow the creation of applications that require user anthentication at startup.
TKAuthenticator class
Abstract base authenticator. An authenticator defines a method for user authentication.
Only one authenticator may be active at any one time.
Applications wanting to use a custom authentication scheme should create and register an authenticator, and then make it active through the configuration.
procedure AfterConstruction;Defines the auth data on the current session and creates the auth macro expander.
destructor Destroy;Frees the auth macro expander.
procedure DefineAuthData(const AAuthData: TEFNode);Receives an empty node which it should fill with the definitions (names and types, not values) of all required auth items. The system uses this information at login time, so that the user can supply any auth data needed by the currently active authenticator. The most common example of auth data is a UserName + Password combination.
If no auth items are defined, then the system will not prompt the user but will still call Authenticate passing in an empty node.
function Authenticate(const AAuthData: TEFNode): Boolean;Checks whether the specified auth data designates a valid user or not, and returns False if the authentication fails.
function RehydrateAuthData(const AUserName: string;Refills AAuthData from the user record WITHOUT checking a password, for an identity already proven by other means — a validated JWT whose server-side session was lost (timeout, restart) and re-created empty. Authenticate seeds the auth data at login (the imposed-step flags MUST_CHANGE_PASSWORD / MUST_CONFIRM_ACCESS, and any %Auth:field% a view reads), but that state lives on the session and is gone once the session is; a token outlives the session, so the identity survives while the data behind it does not, and the imposed-step gate — which reads the flags out of the auth data — would wave the request through. Returns False when the user can no longer be established (unknown, deactivated, deleted), so the caller can refuse the token: this is also how a disabled account's still-valid token stops working. The default does nothing and returns True (authenticators with no user record to reload, e.g. TextFile/OSDB, carry all they need in the token).
property AuthData: TEFNode read GetAuthData;Gives access to a copy of the auth data that was last passed to Authenticate (and possibly modified by the object during authentication).
procedure Logout;Clears AuthData and turns off IsAuthenticated.
property UserName: string read GetUserName;A unique identifier for the currently logged in user. The value depends on the particular descendant. By default, it's 'PUBLIC'.
property Password: string read GetPassword write SetPassword;For password-based authenticators, returns the current user's password or hash. The default implementation returns a blank string.
property SecretCode: string read GetSecretCode;For PIN-based authenticators, returns the current user's secret code (to generate the 6-digit one time PIN). The default implementation returns a blank string.
property IsClearPassword: Boolean read GetIsClearPassword;Returns True if the autheticator uses clear passwords, False if hashing is used. Only meaningful for password-based authenticators. By default, returns True.
property IsAuthenticated: Boolean read GetIsAuthenticated;Returns True if authentication has successfully taken place.
property MustChangePassword: Boolean read GetMustChangePassword;Returns True if the authentication data signals that the user must change his password. By default, this happens when a custom field called MUST_CHANGE_PASSWORD with value 1 is added to the authentication data. Querying this property is only meaningful after successful authentication.
property MustConfirmAccess: Boolean read GetMustConfirmAccess;Returns True if the authentication need to confirm a pre-requisite to access to system.
procedure ResetPassword(const AParams: TEFNode);Called (with no authenticated user) when a password reset is initiated. Override this method to implement an application-defined scheme, such as generating a random password and emailing it to the user. The specified params depend on the calling controller. A standard controller might specify the user name (UserName) or email address (EmailAddress) to which the generated password should be sent.
procedure QRGenerate(const AParams: TEFNode);Called (with no authenticated user) when a QR code (for PIN authentication) is requested. Override this method to implement an application-defined scheme, such as generating a QR code containing the secret to share with the third party authenticator app and emailing it to the user. The specified params depend on the calling controller. A standard controller might specify the user name (UserName) and email address (EmailAddress) to which the generated QR code should be sent.
function IsPasswordMatching(const ASuppliedPasswordHash: string;Returns True if the supplied password hash matches the stored one. Concrete authenticators define the actual matching rules.
property IsBCrypted: Boolean read GetIsBCrypted write FIsBCrypted;Indicates whether the stored password is hashed with the BCrypt algorithm (as opposed to the legacy hash or clear text).
function SupportsPasswordChange: Boolean;Tells whether this authenticator is able to write a new password to wherever it keeps credentials. The default is True: every password-based authenticator overrides SetPassword and can honour a change.
Authenticators that do NOT own the credentials return False — the directory-backed ones (Auth: LDAP) being the case in point: passwords live in the directory and must be changed there. Returning False is not cosmetic: SetPassword's base implementation has an EMPTY body, so without this the change-password handler would report success and write nothing at all. Callers MUST consult this before writing (see Kitto.Web.Handler.Auth.HandleChangePassword) and SHOULD consult it before offering the UI (see Kitto.Html.ChangePassword).
function EffectiveConfigNode: TEFTree;Returns the configuration node callers consult for user-facing auth options (DatabaseChoices, ValidatePassword, IsPassepartoutEnabled, ...). It is the authenticator's own Config: with the flat Auth model those keys live directly under the Auth node, whether or not a JWT block is present.
procedure AuthorizeRequest;Per-request hook invoked by TKWebApplication just after ActivateInstance and before any route dispatch. When IsJWTEnabled it delegates to the registered IKXJWTEngine to validate the request token, hydrate the session and slide the expiration; otherwise it does nothing. Kept virtual so a custom authenticator can still add per-request work.
function IsJWTEnabled: Boolean;True when this authenticator is configured to issue/validate a JWT — i.e. a JWT sub-node is present under its Auth config. When True the base delegates token issue/validate/clear to the registered IKXJWTEngine, and the credential itself carries the session id ('sid' claim), so the engine must NOT emit a separate session-id cookie.
function IssueToken: string;Issues the JWT cookie for the just-authenticated user and returns the compact token when IsJWTEnabled; otherwise returns ''. Delegates to the registered IKXJWTEngine. Used by the REST /token endpoint.
property JWTState: TObject read FJWTState write SetJWTState;Opaque per-authenticator state owned by the JWT engine (see the field). Public so the engine can attach/read its parsed config; the base frees it. Assigning a new value frees the previous one.
IKXJWTEngine interface
Crypto/transport engine for the optional JWT envelope. The base TKAuthenticator decides WHEN to issue/validate/clear a token (from the presence of a JWT sub-node in its config) but delegates the actual signing and validation — and the third-party JOSE dependency — to an engine registered by an opt-in unit (Kitto.Auth.JWT). Applications that do not use JWT never link JOSE.
function IssueToken(const AAuthenticator: TKAuthenticator): string;Builds and writes the JWT cookie for a just-authenticated user; returns the compact token (for diagnostics).
function AuthorizeRequest(const AAuthenticator: TKAuthenticator): Boolean;Validates the request's token, hydrates the session and slides the expiration. Returns True when the request carries a valid token.
procedure ClearToken(const AAuthenticator: TKAuthenticator);Clears the JWT cookie (logout).
TKClassicAuthenticator class
An abstract authenticator that requires UserName and Password as auth data.
How the auth data is checked is deferred to the concrete descendants. The value of the UserName auth item is also used as the value for the UserName property.
TKNullAuthenticator class
The Null authenticator does not require authentication data and always grants authentication. It is used by default.
function SupportsPasswordChange: Boolean;There is no credential store at all here, so the three members below cannot do anything meaningful. They are implemented rather than left abstract because abstract members of a factory-created class do not fail at build time: they raise "Abstract Error" the first time a user reaches the feature, which is a crash instead of an explanation.
procedure ResetPassword(const AParams: TEFNode);Raises: there is no account whose password could be reset.
procedure QRGenerate(const AParams: TEFNode);Raises: no per-user secret exists to enrol a device with.
function IsPasswordMatching(const ASuppliedPasswordHash: string;Always False. No password is stored, so nothing can match one, and returning True would make an empty password look verified.
TKAuthenticatorRegistry class
This class holds a list of registered authenticator classes.
class destructor Destroy;Frees the singleton registry instance.
procedure RegisterClass(const AId: string;Adds an authenticator class to the registry.
TKAuthenticatorFactory class
Creates authenticators by Id.
class destructor Destroy;Frees the singleton factory instance.
function CreateObject(const AClassId: string): TKAuthenticator;Creates and returns an instance of the authenticator class identified by AClassId. Raises an exception if said class is not registered.
Routines
procedure RegisterJWTEngine(const AEngine: IKXJWTEngine);Registers the JWT engine — called from Kitto.Auth.JWT's initialization. The last registration wins.
function GetJWTEngine: IKXJWTEngine;The registered JWT engine, or nil when no JWT-capable unit is linked into the application.
