⚙️ Configuration
Essential settings for development and production environments
🗄️ Database Configuration
"Database": {
"DatabaseType": "mongodb",
"ConnectionString": "mongodb://localhost:27017",
"DatabaseName": "BlazorBlueprint"
}
Production: Use MongoDB Atlas or self-hosted MongoDB with authentication.
⚡ Redis Configuration
"ConnectionStrings": {
"redisCache": "localhost:6379"
},
"Caching": {
"UseRedisDistributedCache": true,
"UseRedisSignalRBackplane": true
}
What Redis Provides:
- Distributed Cache: Fast API response caching
- SignalR Backplane: Real-time messaging across multiple instances
- Session Persistence: Users stay logged in across deployments
🔐 Authentication Configuration
Configure the shared auth cookie domain and external login providers. The Cookie:Domain should be set to your platform's parent domain (with a leading dot) so the auth cookie is shared across tenant subdomains.
"Authentication": {
"Cookie": {
"Domain": ".yourdomain.com"
},
"Facebook": {
"AppId": "your-facebook-app-id",
"AppSecret": "your-facebook-app-secret"
},
"Google": {
"ClientId": "your-google-client-id",
"ClientSecret": "your-google-client-secret"
},
"Microsoft": {
"ClientId": "your-microsoft-client-id",
"ClientSecret": "your-microsoft-client-secret"
}
}
Provider setup: Create an app in the Facebook Developer Portal, Google Cloud Console, or the Azure Portal → App Registrations. Register your platform domain as the OAuth redirect URI:
- Facebook: Valid OAuth Redirect URI =
https://yourdomain.com/signin-facebook - Google: Authorized Redirect URI =
https://yourdomain.com/signin-google - Microsoft: Redirect URI =
https://yourdomain.com/signin-microsoft(register as a Web platform in the Azure app registration). Uses the/commonendpoint by default, so the button accepts both personal Microsoft accounts and work/school accounts. - Facebook Data Deletion: Data Deletion Request URL =
https://yourdomain.com/api/Facebook/DeleteUserData
Only one redirect URI per provider is needed — tenant subdomains route their login flows through the platform host automatically. Credentials from appsettings are seeded into the platform organisation's External Authentication settings during initial setup and can be managed via Platform → External Authentication.
Organisations on their own custom domain must register their own Facebook/Google/Microsoft app and configure it via Admin → External Authentication. OAuth credentials are domain-bound, so the platform's app will not work on a custom domain — the login page simply hides those buttons until the org configures its own. This page is only visible to organisations accessed through a verified custom domain; on the platform host and tenant subdomains, external auth is managed at the platform level.
📧 Email Configuration
"Email": {
"Enabled": true,
"Provider": "MailerSend", // MailerSend, SendGrid, SMTP
"ApiKey": "your-api-key",
"SenderEmail": "support@yourdomain.com",
"SmtpHost": "", // SMTP only
"SmtpPort": 587, // SMTP only
"SmtpUseSsl": true, // SMTP only
"SmtpUsername": "", // SMTP only
"SmtpPassword": "", // SMTP only
"Domain": "",
"Region": ""
}
🔐 Per-Organisation SSO (OIDC)
Individual organisations can connect their own OpenID Connect identity provider (Okta, Auth0, Entra ID, etc.)
via Admin → SSO (/Admin/Sso). Credentials are stored on the Organisation
document so they can be resolved before tenant context is established.
The scheme is registered once at startup as oidc-org; per-request options (authority, client id,
client secret, scopes) are applied dynamically based on the resolved organisation. Users signing in via the
org's SSO are matched to existing accounts by email or provisioned on first login.
🌐 Custom Domains & Verification
When Features:CustomDomainOrganisations is enabled, organisation admins can list custom
hostnames on their organisation and prove ownership via a DNS TXT record before the domain is considered
verified. Requests on a verified custom domain resolve directly to that organisation.
"DomainVerification": {
"TxtRecordPrefix": "blazorblueprint-verify=",
"TokenHmacSecret": "your-long-random-secret"
}
An organisation admin sets the domain under Admin → Organisation Settings, then publishes a
TXT record of the form {TxtRecordPrefix}{orgToken} on that domain. Verification is checked via
public DNS resolvers (Cloudflare, Google) both immediately on request and by a background job that re-checks
every few hours, with a small failure threshold before a previously verified domain is demoted.
The orgToken is deterministic: HMAC-SHA256(TokenHmacSecret, orgName + ":" + domain),
truncated to 24 hex chars. Re-creating the same org with the same domain after a dev-environment DB reset
produces the same token, so an existing DNS TXT record keeps verifying without touching the zone. Different
orgs get different tokens for the same domain (because orgName is in the hash), which means a
leftover TXT record from a previous tenant of a domain does not let a different org
auto-verify. Set TokenHmacSecret to a long random string in production so tokens can't be
pre-computed without the secret; if it's blank the system falls back to an unkeyed SHA-256 with a
startup warning.
👤 User Deletion & Grace Period
User account deletion is soft by default: a deletion request marks the user and blocks sign-in, but the
account is only purged once the grace window expires. During the grace window the user can sign in to
/Account/DeletionStatus and cancel the request. This also powers the Facebook Data Deletion
Request callback at /api/Facebook/DeleteUserData.
"BackgroundServices": {
"UserDeletion": {
"GracePeriodDays": 30
}
}
📬 Kafka Pipelines & Message Signing
Two feature flags move work off the web process and onto the background worker via Kafka: push notifications
(Features:UseKafkaPushNotificationPipeline) and the API request pipeline
(Features:UseKafkaApiPipeline). Messages are signed with HMAC-SHA256 using a shared secret so the
worker can verify they originated from a trusted producer before dispatching them.
"Kafka": {
"BootstrapServers": "kafka:9092",
"MessageSigningKey": "your-shared-secret-here"
}
If MessageSigningKey is not set the system falls back to unsigned messages with a startup warning
— this is fine for local development but should always be configured in production.
🔑 Application Service API Credentials
The Blazor Web app talks to the separate Application Service API (Services/BlazorBlueprint.ApplicationService,
default port 8081) using a JWT client-credentials flow. The shared secret and JWT signing key must match
between the two projects.
"Security": {
"WebApp": {
"ClientSecret": "shared-client-secret"
},
"Jwt": {
"SecretKey": "jwt-signing-key"
}
},
"Services": {
"ApplicationService": {
"Url": "http://localhost:8081"
}
}
📦 Ready to Download?
Configure and deploy your SaaS application with Blazor Blueprint. Download the free Developer version or get Enterprise for commercial use and premium plugins.
🔓 Open Source on GitHub • Free for personal/non-commercial use • Enterprise license (£399) required for commercial use • Full source code included