SqlOS

AuthServer

Password Login

Authenticate users with email and password.

4 sections

Password login uses email + password. Run home realm discovery first. It tells you password vs SSO before you show a form.

Home realm discovery#

Given an email address, discovery returns the login mode:

CSHARP
var discovery = await discoveryService.DiscoverAsync(
    new SqlOSHomeRealmDiscoveryRequest("user@acme.com"), ct);
 
// discovery.Mode → "password" or "sso"
ModeMeaning
passwordNo SSO org for this email — show password
ssoDomain maps to SAML — redirect to IdP

Frontend example (Next.js):

TYPESCRIPT
const res = await fetch("/api/v1/auth/discover", {
  method: "POST",
  body: JSON.stringify({ email }),
});
const { mode, organizationId } = await res.json();
 
if (mode === "sso") {
  // Start SSO flow
} else {
  // Show password input
}

Login flow#

CSHARP
var result = await authService.LoginWithPasswordAsync(
    new SqlOSPasswordLoginRequest(email, password, clientId, organizationId: null),
    httpContext, ct);
 
if (result.RequiresOrganizationSelection)
{
    // User belongs to multiple orgs
    // Present result.Organizations, then:
    var tokens = await authService.SelectOrganizationAsync(
        new SqlOSSelectOrganizationRequest(result.PendingAuthToken, selectedOrgId),
        httpContext, ct);
}
else
{
    var accessToken = result.Tokens.AccessToken;
    var refreshToken = result.Tokens.RefreshToken;
}

Password step in hosted auth

Frontend integration#

A typical frontend flow using the example API endpoints:

TYPESCRIPT
// 1. Discover login mode
const discover = await apiPost("/api/v1/auth/discover", { email });
 
// 2. Login with password
const login = await apiPost("/api/v1/auth/login", {
  email,
  password,
  organizationId: discover.organizationId,
});
 
if (login.requiresOrganizationSelection) {
  // Show org picker, then:
  const tokens = await apiPost("/api/v1/auth/select-organization", {
    pendingAuthToken: login.pendingAuthToken,
    organizationId: selectedOrgId,
  });
}
 
// 3. Store tokens
localStorage.setItem("access_token", login.accessToken);

Configuration#

Disable password auth entirely:

CSHARP
builder.AddSqlOS<AppDbContext>(options =>
{
    options.AuthServer.EnableLocalPasswordAuth = false;
});

Require verified email before password login:

CSHARP
builder.AddSqlOS<AppDbContext>(options =>
{
    options.AuthServer.RequireVerifiedEmailForPasswordLogin = true;
});