AngryMonkey.CloudLogin.Server
1.5.0
dotnet add package AngryMonkey.CloudLogin.Server --version 1.5.0
NuGet\Install-Package AngryMonkey.CloudLogin.Server -Version 1.5.0
<PackageReference Include="AngryMonkey.CloudLogin.Server" Version="1.5.0" />
<PackageVersion Include="AngryMonkey.CloudLogin.Server" Version="1.5.0" />
<PackageReference Include="AngryMonkey.CloudLogin.Server" />
paket add AngryMonkey.CloudLogin.Server --version 1.5.0
#r "nuget: AngryMonkey.CloudLogin.Server, 1.5.0"
#:package AngryMonkey.CloudLogin.Server@1.5.0
#addin nuget:?package=AngryMonkey.CloudLogin.Server&version=1.5.0
#tool nuget:?package=AngryMonkey.CloudLogin.Server&version=1.5.0
CloudLogin
Authentication, account, profile, and coordinated-session packages for .NET 10, Blazor, and .NET MAUI.
CloudLogin is secure by default: HTTPS-only cookies, exact redirect allowlists, encrypted authentication tickets and return state, rate-limited authentication endpoints, protected profile mutations, modern password hashing, and coordinated authority logout are enabled by the standard registration methods.
Table of contents
- Projects and packages
- Architecture
- Standalone login website
- Consumer website
- Embedded website
- .NET MAUI
- Feature overview
- Authentication providers
- Configuration reference
- Endpoints developers commonly use
- Developer implementation checklist
- Secure defaults
- Production key and secret management
- Production startup troubleshooting
- Migration notes
- Security scope
- Additional guidance
Projects and packages
Architecture
CloudLogin is organized into a few clear layers:
- Contracts layer (
AngryMonkey.CloudLogin.Contracts): shared DTOs, request/response models, provider definitions, and routing helpers. - Authority runtime layer (
AngryMonkey.CloudLogin.Server+AngryMonkey.CloudLogin.API): authentication orchestration, provider wiring, account/user/request endpoints, and security enforcement. - Authority host/UI layer (
AngryMonkey.CloudLogin.Web,AngryMonkey.CloudLogin.Components,AngryMonkey.CloudLogin.WebAssembly): standalone Blazor UI and account/login component experience. - Consumer integration layer (
AngryMonkey.CloudLogin.Serverpackage usage in external apps): redirects to authority, callback handling, local cookie issuance, coordinated logout. - Mobile layer (
AngryMonkey.CloudLogin.Maui): MAUI-native login initiation, callback handling, and secure local session storage. - Client SDK layer (
AngryMonkey.CloudLogin.Client): typed API access for programmatic interactions.
Relationship map:
CloudLogin.Webhosts the authority UI and composesCloudLogin.Components+CloudLogin.WebAssembly.CloudLogin.Serverdepends on contract models and configures provider authentication plus security policies.CloudLogin.APIexposes HTTP endpoints that call intoICloudLogin/server services.CloudLogin.Clientconsumes the API surface using the same models fromCloudLogin.Contracts.- Consumer websites and MAUI apps authenticate against the CloudLogin authority URL.
Integration patterns:
- Standalone authority + consumer website(s) (most common)
- Deploy one CloudLogin authority site.
- Consumer apps use
AddCloudLoginServer("https://login.example.com").
- Embedded authority in existing ASP.NET Core host
- Add CloudLogin services/components directly to an existing site.
- Mobile + authority
- MAUI app uses
AddMauiCloudLogin(...)and authority callback scheme allowlist.
- MAUI app uses
Standalone login website
The complete setup is configuration plus one run call:
using AngryMonkey.CloudLogin.Server;
using AngryMonkey.CloudLogin.Sever.Providers;
var builder = WebApplication.CreateBuilder(args);
builder.AddCloudLoginWeb(options =>
{
options.Cosmos = new(builder.Configuration.GetSection("Cosmos"));
options.AzureStorage = new(builder.Configuration.GetSection("Storage"));
options.Providers =
[
new LoginProviders.GoogleProviderConfiguration(
builder.Configuration.GetSection("Google"))
];
// Optional UI customization.
options.WebConfig = web => web.PageDefaults.SetTitle("Company Login");
});
await CloudLoginWeb.InitApp(builder);
The redirect and mobile allowlists are optional. With no additional configuration, CloudLogin permits relative and same-origin redirects and denies external destinations. Only register callbacks for features the application uses:
builder.AddCloudLoginWeb(options =>
{
options
.AllowWebsite("https://app.example.com")
.AllowWebsite("https://portal.example.com")
.AllowMobileApp("myapp");
// Other configuration...
});
HTTP website origins are accepted only for loopback development addresses. Cosmos,
Azure Storage, external providers, UI customization, website callbacks, and mobile
callbacks are feature-based configuration rather than startup requirements.
Consumer website
Register CloudLogin using the authority URL:
builder.Services.AddCloudLoginServer("https://login.example.com");
Or keep the URL in configuration:
{
"LoginUrl": "https://login.example.com"
}
builder.Services.AddCloudLoginServer(new CloudLoginServerConfiguration
{
LoginUrl = builder.Configuration["LoginUrl"]
});
Use the standard ASP.NET Core pipeline:
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
The consumer callback state is encrypted and integrity-protected with ASP.NET Core Data Protection. Logout clears both the consumer cookie and the CloudLogin authority session before returning to the website.
Embedded website
builder.Services.AddCloudLoginEmbedded(loginOptions, builder.Configuration);
var app = builder.Build();
app.UseHttpsRedirection();
app.UseRouting();
app.UseCloudLoginSecurity();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
UseCloudLoginSecurity enables authentication rate limiting, secure response headers, sensitive-response no-store headers, and same-origin checks for state-changing browser requests.
.NET MAUI
builder.AddMauiCloudLogin(
"https://login.example.com",
"myapp");
Add the same scheme with AllowMobileApp("myapp") on the authority. CloudLogin handles the platform callback, stores the local session in MAUI SecureStorage, and uses the system authentication browser. Logout clears both local secure storage and the authority browser session. An interrupted authority logout is retried before the next login.
Feature overview
CloudLogin includes:
- Standalone authority website (
AngryMonkey.CloudLogin.Web) with built-in login and account UI. - Embedded authority mode for integrating CloudLogin directly inside an existing ASP.NET Core host.
- Consumer-site integration (
AngryMonkey.CloudLogin.Server) with secure login, callback, profile redirect, and coordinated logout endpoints. - .NET MAUI support (
AngryMonkey.CloudLogin.Maui) with mobile callback scheme support. - Blazor/WebAssembly UI components (
AngryMonkey.CloudLogin.Components+AngryMonkey.CloudLogin.WebAssembly) for login and account flows. - Typed client/contracts packages for programmatic integration and shared models.
- Account profile management (name, locale, country, profile image upload).
- Multi-input identity support (email and phone number formats).
- Global admin user-management experience in account UI.
- Test mode provider for controlled test-account sign-in.
Authentication providers
CloudLogin provider configurations are defined in AngryMonkey.CloudLogin.Sever.Providers.LoginProviders (and LoginTestProviders):
| Provider | Configuration type | External IdP | Handles | Typical use |
|---|---|---|---|---|
| Password | PasswordProviderConfiguration |
No | Email/password | Primary username+password sign-in |
| Code (OTP) | CodeProviderConfiguration |
No | Email verification code | Passwordless/verification-code flow |
| Microsoft | MicrosoftProviderConfiguration |
Yes | OAuth/OIDC + email claims | Microsoft Entra ID / Microsoft account sign-in |
GoogleProviderConfiguration |
Yes | OAuth + profile claims | Google account sign-in | |
FacebookProviderConfiguration |
Yes | OAuth + profile claims | Facebook account sign-in | |
TwitterProviderConfiguration |
Yes | OAuth | X/Twitter account sign-in | |
WhatsAppProviderConfiguration |
No (custom transport) | Phone + verification code send path | Phone-based code delivery | |
| Test Mode | LoginTestProviders.TestModeConfiguration |
No | Internal test identities | Integration/UAT test sign-in |
Example mixed provider registration:
builder.AddCloudLoginWeb(options =>
{
options.Cosmos = new(builder.Configuration.GetSection("Cosmos"));
options.AzureStorage = new(builder.Configuration.GetSection("Storage"));
options.Providers =
[
new LoginProviders.PasswordProviderConfiguration(builder.Configuration.GetSection("Password")),
new LoginProviders.CodeProviderConfiguration(builder.Configuration.GetSection("Code")),
new LoginProviders.GoogleProviderConfiguration(builder.Configuration.GetSection("Google")),
new LoginProviders.MicrosoftProviderConfiguration(builder.Configuration.GetSection("Microsoft")),
new LoginProviders.FacebookProviderConfiguration(builder.Configuration.GetSection("Facebook")),
new LoginProviders.TwitterProviderConfiguration(builder.Configuration.GetSection("Twitter")),
new LoginProviders.WhatsAppProviderConfiguration(builder.Configuration.GetSection("WhatsApp")),
new LoginTestProviders.TestModeConfiguration(builder.Configuration.GetSection("TestMode"))
];
});
Configuration reference
Minimal configuration template (fill only sections for enabled features/providers):
{
"Cosmos": {
"ConnectionString": "<cosmos-connection-string>",
"DatabaseId": "CloudLogin",
"ContainerId": "Users"
},
"Storage": {
"ConnectionString": "<storage-connection-string>",
"PublicBaseUrl": "https://<account>.blob.core.windows.net/<container>"
},
"Google": {
"ClientId": "<google-client-id>",
"ClientSecret": "<google-client-secret>",
"Label": "Google"
},
"Microsoft": {
"ClientId": "<microsoft-client-id>",
"ClientSecret": "<microsoft-client-secret>",
"TenantId": "common",
"Label": "Microsoft"
},
"Facebook": {
"ClientId": "<facebook-client-id>",
"ClientSecret": "<facebook-client-secret>",
"Label": "Facebook"
},
"Twitter": {
"ClientId": "<twitter-api-key>",
"ClientSecret": "<twitter-api-secret>",
"Label": "Twitter"
},
"WhatsApp": {
"RequestUri": "<provider-request-uri>",
"Authorization": "<auth-header-value>",
"Template": "<message-template>",
"Language": "en",
"Label": "WhatsApp"
},
"TestMode": {
"IsEnabled": false,
"Label": "Test Mode"
}
}
Endpoints developers commonly use
Consumer-site endpoints from AuthController:
GET /auth/login?returnUrl=/path- start login at CloudLogin authority.GET /auth/callback- login callback that creates the local auth cookie.GET /auth/profile?returnUrl=/path- redirect authenticated user to authority account page.GET /auth/profileCallback- returns to local application from account flow.GET|POST /auth/logout?returnUrl=/- coordinated logout (consumer + authority).
Authority/API endpoints (selected):
GET /CloudLogin/Login/{identity}- begin provider flow.GET /CloudLogin/Result- OAuth/OIDC callback target.GET /CloudLogin/Login/Complete- build completion redirect.GET /CloudLogin/Logout- authority logout endpoint.GET /api/Providers- list available providers for UI.GET /CloudLogin/User/GetUserByInput- public account discovery (rate-limited, transport-safe).POST /CloudLogin/User/Update- authenticated profile update with server-side field protections.POST /CloudLogin/User/UploadProfilePicture- authenticated profile image upload.GET /CloudLogin/Request/GetUserByRequestId- resolve request-id to transport-safe user model.
Developer implementation checklist
- Select deployment mode: standalone authority, consumer integration, or embedded.
- Configure HTTPS and redirect/mobile callback allowlists (
AllowWebsite,AllowMobileApp). - Register providers explicitly; only configured providers are available.
- Configure shared Data Protection key ring for multi-instance deployments.
- Store secrets in a managed secret store (Key Vault, etc.), not in source.
- Validate provider callback URLs (
/CloudLogin/Result) in external IdP configuration. - Enable app monitoring for auth failures, 429s, and provider callback errors.
- If using MAUI, ensure callback scheme matches
AllowMobileAppon authority.
Secure defaults
- Authentication cookies use
Secure,HttpOnly,SameSite=Lax,Path=/, and the browser-enforced__Host-prefix. - Session idle timeout is eight hours; persistent sign-in defaults to 30 days.
- Cookie tickets and consumer return state use ASP.NET Core Data Protection encryption and integrity protection.
- Authentication attempts and public account-discovery calls are rate limited per remote address.
- Passwords use versioned PBKDF2-HMAC-SHA256 with 600,000 iterations and a unique 128-bit salt. Valid older 100,000-iteration hashes are upgraded after the next successful login.
- New passwords accept passphrases and Unicode, require 12–128 characters, reject control characters, and support an application blocklist.
- Password hashes are never serialized into browser authentication tickets or API responses.
- Profile APIs enforce ownership; role, lock, credential-provider, and identifier fields remain server-managed.
- Profile images are size-limited, signature-checked, and restricted to PNG, JPEG, GIF, or WebP; active SVG uploads are rejected.
- Locked users are rejected consistently across password, test, OAuth handoff, and legacy login paths.
- Production startup rejects disabled HTTPS, unsafe redirect origins, test login, weak hash settings, invalid cookie settings, and browser-managed verification-code providers.
- Authentication endpoints send
no-storeresponses and deny framing.
Customize only when required:
builder.AddCloudLoginWeb(options =>
{
options.AllowWebsite("https://app.example.com");
options.Security.MinimumPasswordLength = 15;
options.Security.AuthenticationPermitLimit = 5;
options.Security.PasswordBlocklist.Add("company-name-2026");
// Only needed when copying provider avatars into your own storage.
options.Security.AllowedProfileImageHosts.Add("lh3.googleusercontent.com");
});
Security controls cannot be weakened below the enforced production minimums. Test mode
is disabled by default and is enabled in any environment only when its provider has
IsEnabled set to true. The deprecated browser-managed verification-code flow still
fails startup when explicitly configured because it cannot be made safe for production.
Production warning: Test Mode deliberately signs in selected test accounts without external identity verification. When enabling it in Production, restrict access to the login deployment with network, gateway, or equivalent access controls and ensure test accounts have only the permissions required for testing.
Production key and secret management
ASP.NET Core encrypts CloudLogin cookies and return state with Data Protection. A multi-instance deployment must persist its Data Protection key ring in a shared protected store. Configure this in the host before CloudLogin registration, for example with Azure Blob Storage plus Key Vault, Redis, or another supported shared key-ring provider.
builder.Services
.AddDataProtection()
.SetApplicationName("Company.CloudLogin");
// Add the persistence and key-encryption provider used by your platform.
Operational requirements:
- Store OAuth secrets, Cosmos credentials, storage credentials, and Data Protection key-encryption keys in a managed secret store. Never commit them to
appsettings.json. - Enforce HTTPS at the edge and application, and enable HSTS in production.
- When running behind a reverse proxy, configure ASP.NET Core forwarded headers with an explicit trusted-proxy/network allowlist before authentication middleware; never trust forwarded headers from arbitrary clients.
- Enable Cosmos DB and storage encryption at rest; use customer-managed keys where required by organizational policy.
- Put internet-facing deployments behind a WAF/DDoS service. Application rate limiting is not a replacement for edge protection.
- Restrict health endpoints to non-sensitive status and monitor authentication failures, 429 responses, provider errors, and administrative actions without logging credentials, authorization codes, request IDs, or personal data.
- Back up the Data Protection key ring. Losing it invalidates active cookies; disclosing it can compromise protected payloads.
Production startup troubleshooting
An IIS 500.30 response means the application failed before it could serve its normal
error page. Check Windows Event Viewer first. For a short diagnostic window, enable the
ASP.NET Core Module stdout log in the published web.config and ensure the application
pool identity can write to the selected folder:
<aspNetCore processPath="dotnet"
arguments=".\Your.Login.dll"
stdoutLogEnabled="true"
stdoutLogFile=".\logs\stdout"
hostingModel="inprocess" />
Disable stdout logging again after capturing the startup exception; logs can grow without limit and may contain deployment details. An enabled test-mode provider is supported in Development, Staging, and Production and no longer causes a startup failure.
Migration notes
The secure defaults intentionally tighten previous behavior:
- Default cookies are now
__Host-CloudLoginand__Host-CloudLogin.Consumer; existing sessions will sign in again once. - Password registration now requires at least 12 characters. Existing passwords continue to work and their hashes upgrade after successful authentication.
- Test mode is disabled by default. When explicitly enabled, it is available in Development, Staging, and Production.
- Client-managed email/WhatsApp verification codes are disabled. The former flow exposed verification state to browser code and is not suitable for production authentication.
- Shared parent-domain cookies are no longer inferred from
BaseAddress. Prefer coordinated login/logout. If a shared cookie is explicitly required, setCookieDomainand use a cookie name without the__Host-prefix after completing a subdomain threat review.
Security scope
These controls provide a strong framework baseline, not automatic regulatory certification. Enterprise deployment still requires threat modeling, dependency and secret scanning, infrastructure hardening, centralized audit logging, incident response, penetration testing, privacy review, and controls appropriate to the required assurance level.
Additional guidance
- ASP.NET Core Data Protection
- ASP.NET Core rate limiting
- OWASP Password Storage Cheat Sheet
- NIST SP 800-63B
CloudLogin is part of the Angry Monkey Cloud ecosystem and is licensed under the MIT License.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- AngryMonkey.Cloud.Geography (>= 2.8.0)
- AngryMonkey.CloudLogin.Contracts (>= 1.5.0)
- AngryMonkey.CloudWeb.Server (>= 2.4.3)
- Azure.Identity (>= 1.21.0)
- Azure.Security.KeyVault.Certificates (>= 4.9.0)
- Azure.Security.KeyVault.Secrets (>= 4.11.0)
- Azure.Storage.Blobs (>= 12.29.1)
- Microsoft.AspNetCore.App.Internal.Assets (>= 10.0.8)
- Microsoft.AspNetCore.Authentication.Facebook (>= 10.0.8)
- Microsoft.AspNetCore.Authentication.Google (>= 10.0.8)
- Microsoft.AspNetCore.Authentication.MicrosoftAccount (>= 10.0.8)
- Microsoft.AspNetCore.Authentication.OpenIdConnect (>= 10.0.8)
- Microsoft.AspNetCore.Authentication.Twitter (>= 10.0.8)
- Microsoft.AspNetCore.Components.WebAssembly.Server (>= 10.0.8)
- Microsoft.Azure.Cosmos (>= 3.61.0)
- Microsoft.Graph (>= 6.2.0)
- Microsoft.Kiota.Abstractions (>= 2.0.0)
- Newtonsoft.Json (>= 13.0.4)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on AngryMonkey.CloudLogin.Server:
| Package | Downloads |
|---|---|
|
AngryMonkey.CDM.Server
Package Description |
|
|
AngryMonkey.CloudLogin.API
Package Description |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.5.0 | 40 | 7/16/2026 |
| 1.4.6 | 135 | 7/13/2026 |
| 1.4.5 | 118 | 7/12/2026 |
| 1.4.4 | 223 | 7/6/2026 |
| 1.4.3 | 152 | 5/29/2026 |
| 1.4.2 | 131 | 5/29/2026 |
| 1.4.1 | 148 | 5/28/2026 |
| 1.4.0 | 131 | 5/26/2026 |
| 1.3.6 | 132 | 4/29/2026 |
| 1.3.4 | 130 | 4/16/2026 |
| 1.3.3 | 136 | 3/19/2026 |
| 1.3.2 | 139 | 3/6/2026 |
| 1.3.1 | 364 | 6/3/2025 |
| 1.3.0 | 228 | 5/28/2025 |
| 1.2.3 | 338 | 8/12/2024 |
| 1.2.2 | 200 | 8/11/2024 |
| 1.2.1 | 213 | 8/11/2024 |
| 1.2.0 | 196 | 8/11/2024 |