When enterprises want to implement Time-based One-Time Password (TOTP) authentication using Google Authenticator with Active Directory, they face a fundamental architectural decision: whether to use native Windows Server capabilities or extend AD FS with custom development.
Windows Server 2016+ includes native TOTP support through the Microsoft Authenticator app. While not directly compatible with Google Authenticator, the underlying protocol is similar:
# PowerShell to enable MFA for a user
Set-MsolUser -UserPrincipalName user@domain.com -StrongAuthenticationRequirements @{
"Requirements":@(
@{
"RequirementType":"StrongAuthenticationRequirement"
"State":"Enabled"
}
)
}
The Technet solution you referenced demonstrates how to extend AD FS 3.0 with custom authentication providers. Here's a simplified version of the key components:
// Sample C# for custom AD FS adapter
public class GoogleAuthenticatorAdapter : IAuthenticationAdapter
{
public void OnAuthenticationPipelineLoad(IAuthenticationMethodConfigData configData)
{
// Initialization logic
}
public IAdapterPresentation OnError(HttpListenerRequest request, Exception ex)
{
// Error handling
}
}
The solution requires storing TOTP secrets in a SQL database. Here's the essential schema:
CREATE TABLE UserAuthenticatorSecrets (
UserId UNIQUEIDENTIFIER PRIMARY KEY,
SecretKey VARBINARY(256),
ScratchCodes VARBINARY(MAX),
CreatedDate DATETIME,
LastUsedDate DATETIME
);
- Secret key generation must use cryptographically secure RNG
- QR code generation should happen server-side
- The time synchronization window should be configurable (default 30s)
- Implement backup code handling
Commercial products like Duo Security or AuthLite provide pre-built integration between AD and Google Authenticator, often with additional features:
- User self-enrollment portals
- Mobile device management integration
- Advanced reporting and compliance features
Regardless of implementation method:
- Always encrypt TOTP secrets at rest
- Implement rate limiting for authentication attempts
- Maintain audit logs of all MFA operations
- Provide secure recovery mechanisms
When enterprises try to implement Time-based One-Time Password (TOTP) authentication with Active Directory, they often face a fundamental gap: Windows Server lacks native support for RFC 6238 (Google Authenticator standard). The common workaround involves AD FS, but let's explore both integrated and alternative approaches.
While Windows Server doesn't provide out-of-the-box TOTP support, these methods provide varying degrees of integration:
# PowerShell snippet to check MFA capabilities
Get-WindowsFeature *MFA* | Where-Object Installed
Get-Command *OTP* -Module ActiveDirectory
For true native solutions, consider:
- Windows Hello for Business (uses certificate-based auth)
- Microsoft Authenticator app (Azure AD integration)
- Third-party MFA providers with AD sync
The Technet article referenced provides a custom implementation approach. Here's a condensed version of the key components:
// C# sample for custom AD FS adapter
public class GoogleAuthAdapter : IAuthenticationAdapter
{
public bool TryEndAuthentication(IAuthenticationContext authContext,
Claim[] claims, out Claim[] outgoingClaims)
{
// TOTP validation logic here
var userToken = authContext.Data["totp"].ToString();
var isValid = TotpValidator.Validate(userToken);
outgoingClaims = isValid ? claims : null;
return isValid;
}
}
For environments where AD FS isn't available, consider these patterns:
Approach | Complexity | Dependencies |
---|---|---|
RADIUS proxy with FreeRADIUS + pam_google_authenticator | Medium | NPS role, Linux middleware |
LDAP proxy with custom schema extensions | High | Schema modification rights |
Azure AD Premium P1 with Conditional Access | Low | Azure AD Connect |
Key factors for enterprise deployment:
- Secret key storage (HSM vs encrypted DB)
- User provisioning workflows
- Fallback authentication mechanisms
- Audit logging requirements
# Sample SQL schema for TOTP secrets
CREATE TABLE UserTotpSecrets (
UserSid VARBINARY(85) PRIMARY KEY,
SecretKey VARBINARY(256) NOT NULL,
RecoveryCodes VARCHAR(MAX),
LastUsed DATETIME2,
CONSTRAINT FK_UserSid FOREIGN KEY (UserSid)
REFERENCES AD_Objects(objectSid)
) WITH (ENCRYPTION = ON);
For organizations transitioning from password-only to TOTP:
// Pseudocode for phased rollout
foreach (user in Get-ADUser -Filter *) {
if (user.Department -eq "IT") {
Enable-TotpForUser -User $user -EnforcementLevel "Required";
} else {
Enable-TotpForUser -User $user -EnforcementLevel "Optional";
}
if ((Get-Date) -gt $cutoverDate) {
Set-TotpEnforcement -Level "Required";
}
}