Blog

All Blog Posts  |  Next Post  |  Previous Post

Add User Authentication to Your App in a Secure Way

Today

Every application that has users needs authentication. Users need to log in, recover forgotten passwords, confirm their e-mail, maybe set up two-factor authentication. It sounds straightforward until you actually have to build it.

The reality is that authentication is one of the most security-sensitive parts of any application. Getting it wrong — misconfigured headers, missing CSRF protection, a poorly implemented token flow — can expose your users to real harm. And yet most developers aren't security specialists. They just need it to work, and work safely.

TMS Sphinx is an OAuth 2.0 and OpenID Connect authentication server framework for Delphi developers. These are the industry-standard protocols used by every major identity provider — the same protocols behind "Sign in with Google" or corporate SSO systems. Sphinx lets you add a complete, standards-compliant authentication server to your own Delphi application, without depending on third-party cloud services.

At the center of Sphinx is its login web application: a ready-made, browser-based UI that handles the entire user journey:

  • Sign in
  • Sign up (self-registration)
  • Forgot password and reset workflow
  • E-mail and phone number confirmation
  • Two-factor authentication enrollment

Your application redirects to it when a user needs to authenticate, and Sphinx handles the rest. You don't write login UI code. You configure behavior through Delphi properties in the IDE. For example, to get a Sphinx server up and running, you drop a few components on a form, configure them, and start the dispatcher:

procedure TForm1.FormCreate(Sender: TObject);
begin
  AureliusConnection1.Params.Values['Database'] := ChangeFileExt(ParamStr(0), '.db');
  AureliusDBSchema1.UpdateDatabase;
  SparkleHttpSysDispatcher1.Active := True;
end;

That's enough to have a working OAuth2 server with a fully functional login page. But beyond convenience, what makes the Sphinx login app worth using is how seriously it takes security — and how much of that security work it does on your behalf.

No CDN dependencies: it works anywhere, and it's safer

Many web applications load JavaScript libraries and CSS frameworks from public CDN servers — convenient during development, but a real problem in practice.

The deployment problem. If your application runs on a private network, an air-gapped environment, or a customer's intranet without external access, a CDN-dependent login page simply breaks. Users see a broken UI, or no UI at all.

The security problem. A compromised CDN can silently inject malicious code into your login page. That code runs in the user's browser, on your login form, with access to whatever the user types. This is not a theoretical threat; CDN-based supply chain attacks have happened to real companies.

Sphinx's login app loads everything from your own server. No external requests are made during the login flow. This means:

  • It works on any network, including fully offline environments
  • There is no third-party code running on your login page
  • You eliminate an entire class of supply-chain vulnerability

You don't configure this — it's simply how Sphinx works.

Security headers, configured correctly

HTTP security headers are one of those things that security auditors always check and developers routinely forget. Two of the most important ones:

  • Content-Security-Policy — tells the browser what it's allowed to do on a given page: which scripts can run, where resources can be loaded from, and more. A properly configured CSP blocks a wide range of injection attacks.
  • X-Content-Type-Options — prevents browsers from guessing at content types, which can be exploited to execute unintended content as scripts.

Sphinx sends these headers on all login app responses out of the box. You don't need to know what CSP directives to write, and you don't need to configure them at the web server level. They're part of the application.

CSRF protection built in

Cross-site request forgery (CSRF) is an attack where a malicious website tricks a user's browser into making requests to another site — including your application — using the user's existing session. It's consistently listed among the most common web vulnerabilities.

One important defense is the SameSite attribute on session cookies, which controls when the browser will include the cookie in cross-site requests. Sphinx sets SameSite=Lax on its session cookie, blocking the most common CSRF attack vectors. This is not something you configure — it's the default behavior.

Two-factor authentication, from QR code to verified login

Two-factor authentication (2FA) adds a second step to the login process: after entering a password, the user also provides a time-based one-time code from an authenticator app like Google Authenticator or Authy. Even if someone steals a password, they can't log in without the physical device that generates the code.

Sphinx implements 2FA end to end, and the enrollment flow is handled entirely within the login app. To require 2FA for all users, it's a single property:

SphinxConfig1.LoginOptions.RequireTwoFactor := True;

To require it for a specific user only:

procedure RequireTwoFactorForUser(Context: ISphinxContext; const UserName: string);
var
  User: TUser;
begin
  User := Context.UserManager.FindByName(UserName);
  if User = nil then
    raise Exception.Create('User not found');
  Context.UserManager.SetTwoFactorRequired(User, True);
end;

When a user who has 2FA required logs in next, the login app automatically displays a QR code. The user scans it with their authenticator app, enters the generated code to verify setup, and from that point forward every login requires the second factor. You don't build any of that UI — Sphinx provides it.

Refresh tokens with rotation and theft detection

When a user logs in, they receive an access token — a short-lived credential their application presents to prove authentication. When that token expires, the traditional approach is to force the user to log in again. Refresh tokens solve this: a longer-lived credential that allows the application to silently obtain a new access token without interrupting the user.

To enable refresh tokens in Sphinx, add gtRefreshToken to the client's allowed grant types and include the offline_access scope:

Client := SphinxConfig1.Clients.Add;
Client.ClientId := 'myclient';
Client.AllowedGrantTypes := [TGrantType.gtAuthorizationCode, TGrantType.gtRefreshToken];
Client.ValidScopes.Add('openid');
Client.ValidScopes.Add('email');
Client.ValidScopes.Add('offline_access');  // Required for refresh tokens

Sphinx implements refresh tokens with modern security practices:

  • Rotation — each time a refresh token is used, it is invalidated and a new one is issued. The old token cannot be reused.
  • Single-use enforcement — once used, the previous token is marked as consumed.
  • Reuse detection — if a consumed refresh token is presented again, it's a signal the token may have been stolen. Sphinx rejects it with an invalid_grant error.

This significantly reduces the window of damage if a refresh token is ever compromised. The client application should always store the most recently received refresh token and discard the old one.

Accessible by default

Accessibility is often treated as an afterthought. Sphinx's login app implements ARIA attributes — a standard set of HTML annotations that allow screen readers to understand the page structure and communicate it clearly to users with visual impairments. Your login page works for users who depend on assistive technology, without any additional work on your part.

The app is built on Bootstrap 5, ensuring the layout responds correctly to mobile screens and different viewport sizes.

What this means for you as a developer

You don't have to be a security expert to ship a secure login page. Sphinx handles:

  • CSP and security headers
  • CSRF protection via SameSite cookies
  • CDN-free, self-hosted assets
  • 2FA enrollment and verification
  • Refresh token rotation and reuse detection
  • Accessible, responsive UI

What you get to focus on is your application — the business logic, the features, the things that differentiate your product. Authentication is infrastructure. Sphinx is that infrastructure.

Ready to try it? TMS Sphinx is available as a fully functional trial.



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