Customize the Login Screens
You can customize the hosted authentication pages used by the Agglestone Authentication and User Management Service to match your branding.
These pages are rendered by the auth service during login and OAuth2/OIDC flows, so users still authenticate securely on Agglestone-hosted endpoints while seeing your custom design.
Where to Configure It
An admin user can configure custom page HTML in the Agglestone Portal:
- Open
https://portal.agglestone.com - Go to your tenant
- Open Auth Settings
- Add custom HTML for:
- Login page
- Reset password page
- TOTP / 2FA setup page
- TOTP / 2FA verification page
The same verification page templates are used for both authenticator-app (TOTP) and email MFA; the service adjusts messaging (and related styling) when the user is configured to have the second factor delivered by email instead of an app.
Important Behavior
Before custom HTML is stored and rendered:
- Script tags are removed
- External stylesheet links are removed
- External image URLs (
http://,https://,//) are removed - Any form tags are removed and the service injects its own form + hidden fields
For login and reset password pages, validation also requires specific input/button/error elements.
Required Elements by Page Type
Login Page
Your HTML must include:
Optional:
for forgot password UI...
Reset Password Page
Your HTML must include:
(current password)
TOTP / 2FA Setup Page
Recommended elements (expected by injected script):
(the service injects the QR image into this element)
TOTP / 2FA Verification Page
Recommended elements (expected by injected script):
Adding Images with data:image
Because external image URLs are removed, embed images directly using Data URLs:
<img
alt="Logo"
src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2NCIgaGVpZ2h0PSI2NCI+PHJlY3Qgd2lkdGg9IjY0IiBoZWlnaHQ9IjY0IiByeD0iMTIiIGZpbGw9IiMwYjYzZDYiLz48dGV4dCB4PSIzMiIgeT0iMzkiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMjAiIGZpbGw9IndoaXRlIj5BPC90ZXh0Pjwvc3ZnPg=="
/>
You can use:
data:image/svg+xml;base64,...data:image/png;base64,...data:image/jpeg;base64,...data:image/webp;base64,...
Tips:
- Keep assets small (optimize/compress before base64 encoding)
- Prefer SVG where possible for crisp logos with smaller payloads
- Use CSS
background-image: url("data:image/...")for decorative assets
—
Complete Example: Custom Login Page
This is a full login page example that includes all required login fields and IDs:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Login</title>
<style>
:root { font-family: system-ui, Segoe UI, Roboto, Helvetica, Arial, sans-serif; }
body {
min-height: 100vh;
margin: 0;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, #dfe9f3 0%, #ffffff 100%);
}
.card {
width: 380px;
background: #fff;
border-radius: 14px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.08);
padding: 32px;
position: relative;
overflow: hidden;
}
.card::before {
content: "";
position: absolute;
top: -30px;
right: -30px;
width: 120px;
height: 120px;
opacity: 0.15;
background-size: cover;
background-image: url("data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMGI2M2Q2IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48Y2lyY2xlIGN4PSIxMiIgY3k9IjEyIiByPSIxMCIvPjwvc3ZnPg==");
}
.logo {
width: 64px;
height: 64px;
margin: 0 auto 16px;
display: block;
background-size: cover;
background-image: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwIiBoZWlnaHQ9IjEwMCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxjaXJjbGUgY3g9IjEyIiBjeT0iMTIiIHI9IjExIiBmaWxsPSIjMGI2M2Q2Ii8+PHRleHQgeD0iMTIiIHk9IjE2IiBmb250LXNpemU9IjgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZpbGw9IiNmZmYiPkxPR088L3RleHQ+PC9zdmc+");
}
h1 { text-align: center; margin: 0 0 20px; font-size: 22px; font-weight: 600; }
label { display: block; font-size: 13px; margin-bottom: 6px; }
input[type="text"], input[type="password"] {
width: 100%;
padding: 11px 13px;
border: 1px solid #d6dbe0;
border-radius: 8px;
font-size: 14px;
box-sizing: border-box;
}
.row { margin-bottom: 14px; }
#submitBtn {
width: 100%;
padding: 11px 13px;
border-radius: 8px;
border: 0;
background: #0b63d6;
color: #fff;
font-weight: 600;
cursor: pointer;
transition: background 0.2s;
}
#submitBtn:hover { background: #084fa9; }
#submitBtn:disabled { opacity: 0.6; cursor: not-allowed; }
#errorMessage {
color: #b00020;
font-size: 13px;
min-height: 18px;
margin-top: 8px;
text-align: center;
}
#forgotPassword {
text-align: center;
font-size: 13px;
margin-top: 10px;
}
#forgotPassword a {
color: #0b63d6;
text-decoration: none;
font-weight: 500;
cursor: pointer;
}
</style>
</head>
<body>
<main class="card" role="main">
<div class="logo"></div>
<h1>Welcome Back</h1>
<div class="row">
<label for="username">Username</label>
<input name="username" type="text" autocomplete="email" required />
</div>
<div class="row">
<label for="password">Password</label>
<input name="password" type="password" autocomplete="current-password" required />
</div>
<div id="errorMessage" aria-live="polite"></div>
<div class="row">
<button id="submitBtn" type="submit">Sign in</button>
</div>
<div id="forgotPassword">
<a>Forgot your password?</a>
</div>
</main>
</body>
</html>
Complete Example: Custom Reset Password Page
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Reset Password</title>
<style>
body { font-family: system-ui, Segoe UI, Roboto, Helvetica, Arial, sans-serif; background:#f5f7fb; margin:0; }
.wrap { max-width: 420px; margin: 7vh auto; background:#fff; border-radius: 12px; padding: 28px; box-shadow: 0 8px 30px rgba(0,0,0,.08); }
h1 { margin-top:0; font-size: 22px; }
.row { margin-bottom: 14px; }
label { display:block; font-size: 13px; margin-bottom: 6px; }
input { width:100%; box-sizing:border-box; padding:10px 12px; border:1px solid #d6dbe0; border-radius: 8px; }
#submitBtn { width:100%; border:0; border-radius:8px; background:#0b63d6; color:#fff; padding:11px 13px; font-weight:600; }
#errorMessage { color:#b00020; min-height:18px; font-size:13px; margin-top:8px; }
</style>
</head>
<body>
<main class="wrap">
<h1>Reset your password</h1>
<div class="row">
<label for="password">Current password</label>
<input name="password" type="password" autocomplete="current-password" required />
</div>
<div class="row">
<label for="newPassword">New password</label>
<input name="newPassword" type="password" autocomplete="new-password" required />
</div>
<div class="row">
<label for="confirmNewPassword">Confirm new password</label>
<input name="confirmNewPassword" type="password" autocomplete="new-password" required />
</div>
<div id="errorMessage" aria-live="polite"></div>
<button id="submitBtn" type="submit">Reset password</button>
</main>
</body>
</html>
Complete Example: Custom TOTP / 2FA Setup Page
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Set up 2FA</title>
<style>
body { font-family: system-ui, Segoe UI, Roboto, Helvetica, Arial, sans-serif; background:#f5f7fb; margin:0; }
.wrap { max-width: 460px; margin: 7vh auto; background:#fff; border-radius: 12px; padding: 28px; box-shadow: 0 8px 30px rgba(0,0,0,.08); }
h1 { margin-top:0; font-size: 22px; }
p { color:#435065; }
#QRCode img { display:block; margin: 12px auto 18px; width: 180px; height: 180px; }
.row { margin-bottom: 14px; }
input { width:100%; box-sizing:border-box; padding:10px 12px; border:1px solid #d6dbe0; border-radius: 8px; letter-spacing: 2px; text-align:center; font-size:16px; }
#submitBtn { width:100%; border:0; border-radius:8px; background:#0b63d6; color:#fff; padding:11px 13px; font-weight:600; }
#errorMessage { color:#b00020; min-height:18px; font-size:13px; margin:8px 0; }
</style>
</head>
<body>
<main class="wrap">
<h1>Set up 2FA</h1>
<p>Scan the QR code in your authenticator app, then enter the 6-digit code.</p>
<div id="QRCode"></div>
<div class="row">
<label for="totpCode">Verification code</label>
<input id="totpCode" name="totpCode" type="text" inputmode="numeric" maxlength="6" required />
</div>
<div id="errorMessage" aria-live="polite"></div>
<button id="submitBtn" type="submit">Verify and enable</button>
</main>
</body>
</html>
Complete Example: Custom TOTP / 2FA Verification Page
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Verify 2FA</title>
<style>
body { font-family: system-ui, Segoe UI, Roboto, Helvetica, Arial, sans-serif; background:#f5f7fb; margin:0; }
.wrap { max-width: 420px; margin: 7vh auto; background:#fff; border-radius: 12px; padding: 28px; box-shadow: 0 8px 30px rgba(0,0,0,.08); }
h1 { margin-top:0; font-size: 22px; }
.row { margin-bottom: 14px; }
input { width:100%; box-sizing:border-box; padding:10px 12px; border:1px solid #d6dbe0; border-radius: 8px; letter-spacing: 2px; text-align:center; font-size:16px; }
#submitBtn { width:100%; border:0; border-radius:8px; background:#0b63d6; color:#fff; padding:11px 13px; font-weight:600; }
#errorMessage { color:#b00020; min-height:18px; font-size:13px; margin:8px 0; }
</style>
</head>
<body>
<main class="wrap">
<h1>Two-factor verification</h1>
<div class="row">
<label for="totpCode">Enter your 6-digit code</label>
<input id="totpCode" name="totpCode" type="text" inputmode="numeric" maxlength="6" required />
</div>
<div id="errorMessage" aria-live="polite"></div>
<button id="submitBtn" type="submit">Verify</button>
</main>
</body>
</html>
Troubleshooting
- Validation error when saving login page HTML: Check required fields and IDs are present exactly as documented.
- Custom JavaScript not running: Scripts are stripped for security; rely on the service-injected behavior.
- Image is missing: Use
data:image/...instead of external image URLs. - Unexpected form behavior: Do not include your own
tags; the service injects the correct form and hidden fields.
—
Next, you may want to review Login and Logout, Password Management, and Multi-Factor Authentication (MFA).