Authentication strategies for .NET MAUI Blazor Hybrid and WASM

Summary

For a solution containing a .NET MAUI Blazor Hybrid app, a Blazor WebAssembly (standalone, no SSR) app, and a separate ASP.NET Core server, the recommended authentication approaches are:

  1. OpenID Connect/OAuth2 with IdentityServer or Azure AD – central token service hosted in the ASP.NET server.
  2. ASP.NET Core Cookie Authentication + JWT bearer for APIs – server‑side cookies for the web UI and JWTs for native/wasm clients.

Both approaches let the server act as the single source of truth for identity while keeping the client projects lightweight.

Root Cause

The confusion stems from using Blazor Server‑specific scaffolding (which expects a server‑hosted SignalR circuit) in a scenario where:

  • The MAUI app runs natively and cannot maintain a SignalR connection to a server‑side circuit.
  • The WebAssembly app runs entirely in the browser with no server‑side rendering.
  • Authentication must therefore be token‑based rather than relying on server‑side user‑state.

Why This Happens in Real Systems

  • Mixed‑client ecosystems (native + wasm) often share a single back‑end for business logic.
  • Developers copy Blazor Server templates without adapting the auth flow to the client‑side model.
  • Legacy docs still highlight Cookie‑only approaches, which break when the UI runs outside of ASP.NET Core’s request pipeline.

Real-World Impact

  • Login failures on MAUI or WASM clients because the server tries to set an HTTP‑only cookie that the native client cannot store.
  • Security gaps when tokens are mishandled (e.g., storing JWTs in plain local storage without refresh logic).
  • Inconsistent user experience: Web UI appears logged in via cookies, while native UI remains unauthenticated.

Example or Code (if necessary and relevant)

// Program.cs – ASP.NET Core authentication service
builder.Services.AddAuthentication(options =>
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
    options.Authority = "https://login.microsoftonline.com/{tenantId}";
    options.ClientId = "your-client-id";
    options.ResponseType = "code";
    options.SaveTokens = true;
});
// MauiProgram.cs – configuring HttpClient with bearer token
builder.Services.AddHttpClient("AuthAPI", client =>
{
    client.BaseAddress = new Uri("https://api.yourdomain.com/");
})
.AddHttpMessageHandler(() => new AccessTokenHandler());

How Senior Engineers Fix It

  • Centralize auth in the ASP.NET Core server using OpenID Connect or OAuth2.
  • Issue short‑lived JWTs (access token) and long‑lived refresh tokens; store refresh tokens securely (Keychain/Keystore for MAUI, ProtectedBrowserStorage for WASM).
  • Leverage the Microsoft Authentication Library (MSAL) for token acquisition and renewal on both platforms.
  • Configure CORS and token validation consistently across all APIs.
  • Add fallback cookie auth only for the pure web UI when it runs under the same domain as the server.

Why Juniors Miss It

  • They assume cookie authentication works everywhere because it’s the default in many tutorials.
  • Lack of understanding of client‑side token lifecycles and secure storage mechanisms.
  • Over‑reliance on Blazor Server scaffolding without adapting it to Blazor Hybrid or WASM contexts.

Leave a Comment