Blog

All Blog Posts  |  Next Post  |  Previous Post

TMS BIZ July 2026: External Logins, Custom Password Hashing, and More

Thursday, July 9, 2026

The July 2026 update of TMS BIZ is out, and it's a big one for anyone building authenticated, data-driven Delphi backends. The headline is identity brokering in TMS Sphinx — "Login with Google / Microsoft" for your own apps — but there's a lot more under the hood: pluggable password hashing, external-only login pages, chunked streaming in XData, cleaner REST URLs, X.509-based JWT verification in the core library, and a batch of stability fixes across Sparkle and Aurelius.

Here's a tour of what's new, roughly in order of how much it's likely to change the way you build apps.


1. Login with Google, Microsoft and more — identity brokering in TMS Sphinx

TMS Sphinx is an OAuth 2.0 and OpenID Connect authentication and authorization server framework for Delphi. With this release, Sphinx can act as an identity broker: it delegates authentication to an upstream provider like Google or Microsoft Entra, receives the result, maps it to a local user, and still issues its own tokens and manages its own sessions.

In practice, that means you can now add a row of familiar "Continue with Google" / "Sign in with Microsoft" buttons to your login page — or transparently route a corporate customer to their identity provider — with almost no plumbing on your side. PKCE, state, nonce, token validation and user reconciliation are all handled for you.

This feature is large enough to deserve its own article, which walks through registering a provider, adding the buttons, automatic user provisioning, multi-tenant Entra and more:

👉 Login with Google, Microsoft and More — Identity Brokering in TMS Sphinx

The rest of this post covers everything else in the release.


2. Bring your own password hashing (TMS Sphinx)

Sphinx has always hashed and salted stored passwords for you. But security requirements differ: your organization may mandate a specific algorithm (bcrypt, argon2, a particular PBKDF2 configuration), or you may be migrating users from a legacy system whose hashes you need to keep verifying.

You can now replace Sphinx's password hashing entirely. Implement the new IPasswordHasher interface and assign it to TSphinxConfig.PasswordHasher. Every hash and verify operation Sphinx performs goes through your implementation:

uses
  Sphinx.PasswordHasher, Sphinx.Entities;

type
  TBcryptPasswordHasher = class(TInterfacedObject, IPasswordHasher)
  public
    function HashPassword(User: TUser; const Password: string): string;
    function VerifyHashedPassword(User: TUser; const HashedPassword,
      ProvidedPassword: string): Boolean;
  end;

function TBcryptPasswordHasher.HashPassword(User: TUser;
  const Password: string): string;
begin
  // Delegate to your bcrypt/argon2/PBKDF2 routine of choice.
  // The returned value should carry algorithm id, parameters and salt.
  Result := MyBcrypt.HashPassword(Password);
end;

function TBcryptPasswordHasher.VerifyHashedPassword(User: TUser;
  const HashedPassword, ProvidedPassword: string): Boolean;
begin
  Result := MyBcrypt.Verify(ProvidedPassword, HashedPassword);
end;

Wire it up once at startup:

  SphinxConfig1.PasswordHasher := TBcryptPasswordHasher.Create;

When no custom hasher is assigned, Sphinx keeps using its built-in default. A couple of things to keep in mind: the returned hash should embed everything VerifyHashedPassword needs to validate it later, and the implementation is shared across concurrent requests — so make it stateless and thread-safe.


3. External-only login and a smoother sign-out (TMS Sphinx)

Two more Sphinx additions round out the authentication experience.

Hide the password form entirely. If you want users to sign in only through external providers, set:

  SphinxConfig1.LoginOptions.AllowPasswordLogin := False;

The login page then shows just the provider buttons — no username/password fields. (There's a safeguard: if no external providers happen to be available, the local form is still shown so you can't accidentally lock everyone out.)

Redirect back after single sign-out. TSphinxLogin.LogoutAndEndSession and its web counterpart TSphinxWebLogin.LogoutAndEndSession now accept an optional post-logout redirect URI, so the browser can return to a page of your choosing once the SSO session ends:

  SphinxWebLogin1.LogoutAndEndSession('https://myapp.com/goodbye');

For TMS Web Core apps, the new TSphinxWebLogin.ManualCallbackCheck property lets you suppress the automatic OAuth callback check that runs when the component loads, giving you explicit control over when the login flow starts. This release also fixes a Base64 URL-safe decoding issue that affected JWT payloads containing non-ASCII characters in Web Core, and resolves an access violation when AuthResult was read before login.


4. Streaming responses of unknown size (TMS XData)

TMS XData is a framework for building REST APIs in Delphi, built on top of Aurelius and Sparkle. A common pattern is a service operation that returns a TStream — a generated report, an export, a proxied download.

Until now, that stream needed a known size so XData could set Content-Length. This release adds support for streams of unknown size — those whose Size returns a negative value, such as non-seekable pipes or live-generated content. In that case XData automatically switches to chunked transfer encoding instead of a fixed Content-Length:

function TReportService.Export: TStream;
begin
  // A non-seekable stream whose final size isn't known up front.
  // XData sends it with chunked transfer encoding automatically.
  Result := TMyLiveExportStream.Create;
end;

Just as importantly, the stream is now copied to the client in buffered blocks rather than loaded into memory all at once — so large downloads no longer spike your server's memory usage.


5. Cleaner REST URLs with key-as-segment (TMS XData)

By OData convention, XData addresses a single entity with a parenthesized key: /Customer(1). Many REST clients and API gateways prefer the more conventional path-segment style /Customer/1.

The XData client can now speak that dialect. Set the new EntityKeyAsSegment property and the client builds segment-style URLs:

  Client := TXDataClient.Create;
  Client.Uri := 'https://server/tms/xdata';
  Client.EntityKeyAsSegment := True;

  // Requests /Customer/1 instead of /Customer(1)
  Customer := Client.Get<TCustomer>(1);


6. X.509 certificate-based JWT verification (TMS BIZ Core Library)

The TMS BIZ Core Library (BCL) is the foundation the other libraries build on, including the JOSE/JWT implementation used across Sphinx and XData. This release syncs it with the latest upstream Delphi JOSE JWT library and adds several useful capabilities.

The most notable: verifying JWT signatures against an X.509 certificate. If a token issuer publishes its signing key as a PEM-encoded certificate (rather than a raw JWK), you can now extract the public key straight from that certificate:

uses
  Bcl.Jose.Core.JWS, Bcl.Jose.Core.Base;

var
  JWS: TJWS;
begin
  JWS := TJWS.Create(nil);
  try
    JWS.SetKeyFromCert(CertificatePem);   // PEM-encoded X.509 certificate
    JWS.CompactToken := TheJwtToken;
    if JWS.VerifySignature then
      // signature is valid
  finally
    JWS.Free;
  end;
end;

Alongside that, this version brings stricter, safer token handling and a few new helpers:

  • TJWS.CheckCompactToken now validates that each decoded token part is valid UTF-8 and well-formed JSON before accepting the token.
  • New TJOSEBytes.IsValidString and TJSONUtils.IsValidJSON methods let you validate token parts before deserialization.
  • TJWTClaims.ClaimExists is now public, so you can check whether a claim is present.
  • TJSONUtils.SetJSONRttiValue now handles dynamic-array claim values, and new IsJSONBool / GetJSONBool helpers read JSON booleans correctly.
  • JWT validation error messages are more descriptive, making token failures easier to diagnose.
  • A Pointer/Integer cast that misbehaved on 64-bit platforms has been corrected.


7. Aurelius: documented dataset and a cached-updates fix

TMS Aurelius is an ORM framework for Delphi. Two improvements land this cycle.

First, TAureliusDataset — the TDataset descendant that binds Aurelius objects to Delphi's data-aware controls — now has full reference documentation for the class, its associated types, and all public properties and methods, plus an improved guide chapter. If you build VCL/FMX UIs directly over your entities, this fills in a lot of previously undocumented surface area.

Second, a correctness fix in cached updates: when calling TObjectManager.ApplyUpdates with cached updates enabled, extra actions generated during the flush (for example, persisting a new object inside an OnInserted handler) were cached but never executed — silently discarded at the end of the call. Those actions are now applied correctly.


8. Sparkle: stability under real-world conditions

TMS Sparkle is the high-performance HTTP server framework underpinning XData, RemoteDB and Sphinx. Two robustness fixes ship here:

  • The Indy-based server no longer crashes when a client disconnects before the response is sent, in setups using an IOHandler such as TaurusTLS under Linux.
  • Re-entrant requests dispatched synchronously on the same thread — for example, an in-process engine serving a nested request issued from within a handler — no longer lose the outer request's context. Sparkle now saves and restores the previous context instead of clearing it unconditionally.


Getting the update

All of these libraries ship together as part of TMS BIZ. Existing customers can update through their usual channel; if you're evaluating, grab the trial from the TMS Software website.

The quickest way to get the update is with Smart Setup — the free package manager for TMS products. It resolves dependencies, downloads and builds everything for you, so you can move from this announcement to the new bits with a single command:

tms update tms.biz.*

Prefer a UI? The Smart Setup GUI does the same with a single click.

For the full details, see the per-product release notes:

And don't miss the deep dive on the release's marquee feature: Login with Google, Microsoft and More — Identity Brokering in TMS Sphinx.



Wagner Landgraf




This blog post has not received any comments yet.



Add a new comment

You will receive a confirmation mail with a link to validate your comment, please use a valid email address.
All fields are required.



All Blog Posts  |  Next Post  |  Previous Post