How to Add MFA to AWS WorkSpaces with Microsoft Authenticator, NPS, and Active Directory
Step-by-step guide to integrating AWS WorkSpaces with Microsoft Authenticator for multi-factor authentication using NPS RADIUS and an AD domain controller.
Prerequisites
- An AWS WorkSpaces directory (AD Connector or AWS Managed Microsoft AD) that is Registered and working
- A Windows Server (2016 or later) EC2 instance joined to your AD domain
- An Azure AD / Entra ID tenant with Azure AD Premium P1 or P2 licenses
- Azure AD Connect syncing your on-premises AD users to Azure AD
- Users enrolled in Microsoft Authenticator via https://aka.ms/mfasetup
- IAM permissions to modify Directory Service and EC2 security groups
A client came to me after their security team flagged AWS WorkSpaces as a compliance risk — users were authenticating with just a username and password, and there was no multi-factor authentication in place. The fix was to integrate Microsoft Authenticator as the MFA provider using a Network Policy Server (NPS) acting as a RADIUS server, backed by their existing Active Directory domain controller.
This setup is one of the most common MFA architectures for WorkSpaces in enterprises that already run Microsoft infrastructure. It sounds complicated, but once you understand how the pieces fit together, the configuration is straightforward.
Understand the Architecture
The authentication flow works like this:
- User opens the WorkSpaces client and enters their AD credentials
- AWS WorkSpaces sends a RADIUS authentication request to your NPS server
- NPS validates the user’s credentials against Active Directory
- The NPS RADIUS extension triggers a push notification to Microsoft Authenticator on the user’s phone
- User approves the push notification
- NPS returns RADIUS Access-Accept to WorkSpaces
- User is connected to their WorkSpace
The components you need:
| Component | Role | Where It Runs |
|---|---|---|
| AWS WorkSpaces Directory | Sends RADIUS auth requests | AWS (AD Connector or Managed AD) |
| Active Directory Domain Controller | Stores user accounts and group memberships | EC2 or on-premises |
| Network Policy Server (NPS) | Acts as RADIUS server, enforces MFA policy | Windows Server EC2 instance |
| Azure AD / Entra ID | Manages MFA registration and verification | Microsoft cloud |
| NPS Extension for Azure MFA | Bridges NPS to Azure MFA | Installed on the NPS server |
| Microsoft Authenticator | Receives push notifications | User’s mobile device |
Install and Configure the NPS Role
RDP into your Windows Server EC2 instance and install the NPS role. Open PowerShell as Administrator:
Install-WindowsFeature NPAS -IncludeManagementTools
Once installed, open Network Policy Server from Server Manager or run nps.msc.
Register NPS in Active Directory so it has permission to read user account properties:
netsh ras add registeredserver
Alternatively, right-click NPS (Local) in the console and select Register server in Active Directory.
Configure NPS as a RADIUS Server
You need to add the AWS WorkSpaces directory as a RADIUS client. In the NPS console:
- Expand RADIUS Clients and Servers > right-click RADIUS Clients > New
- Configure the client:
| Field | Value |
|---|---|
| Friendly name | AWS-WorkSpaces |
| Address (IP) | The IP addresses of your AD Connector or Managed AD directory endpoints |
| Shared secret | A strong random string (save this — you’ll need it when configuring WorkSpaces) |
To find your directory endpoint IPs:
aws workspaces describe-workspace-directories \
--query "Directories[0].DnsIpAddresses" \
--output json
If you’re using AD Connector, these are the connector IPs. For Managed Microsoft AD, these are the domain controller IPs.
Important: You need to add each directory IP as a separate RADIUS client, or use a single entry with a DNS name that resolves to both IPs.
Generate a strong shared secret:
[System.Web.Security.Membership]::GeneratePassword(32, 8)
Create a Network Policy for WorkSpaces MFA
In the NPS console:
- Expand Policies > right-click Network Policies > New
- Name it
WorkSpaces MFA Policy - On Conditions, add:
- Client Friendly Name: matches
AWS-WorkSpaces - Windows Groups: add the AD security group containing your WorkSpaces users (e.g.,
DOMAIN\WorkSpaces-Users)
- Client Friendly Name: matches
- On Access Permission: select Access granted
- On Authentication Methods:
- Uncheck all except Unencrypted authentication (PAP, SPAP)
- PAP is required because the NPS extension for Azure MFA needs to intercept the plaintext password to validate it before triggering MFA
- On Constraints: leave defaults
- On Settings > RADIUS Attributes > Standard:
- Remove Framed-Protocol
- Remove Service-Type
Click Finish to create the policy.
Important: Move this policy to the top of the processing order. NPS evaluates policies in order and stops at the first match. If a default deny policy is above yours, MFA requests will be rejected.
Install the NPS Extension for Azure MFA
Download the NPS extension from Microsoft:
# Download the NPS extension installer
Invoke-WebRequest -Uri "https://download.microsoft.com/download/B/F/F/BFFB4F12-9C09-4DBC-A4AF-08E51875EEA9/NpsExtnForAzureMfaInstaller.exe" -OutFile "C:\Temp\NpsExtnForAzureMfaInstaller.exe"
Run the installer and follow the wizard. Once installed, you need to configure it with your Azure AD tenant.
Open PowerShell as Administrator and navigate to the extension directory:
cd "C:\Program Files\Microsoft\AzureMfa\Config"
.\AzureMfaConfig.ps1
This script will:
- Prompt you to sign in with Azure AD Global Administrator credentials
- Ask for your Azure AD Tenant ID
- Generate a self-signed certificate for secure communication with Azure AD
- Configure the NPS extension registry settings
Find your Tenant ID in the Azure portal under Azure Active Directory > Properties > Tenant ID, or run:
Connect-AzureAD
(Get-AzureADTenantDetail).ObjectId
Configure the NPS Extension Registry Settings
After the configuration script completes, verify and tune the registry settings:
# Verify the extension is configured
Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\AzureMfa"
Set the authentication mode to push notification only (no phone call fallback):
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\AzureMfa]
"OVERRIDE_NUMBER_MATCHING_WITH_OTP"=dword:00000000
"REQUIRE_USER_MATCH"=dword:00000001
The REQUIRE_USER_MATCH setting ensures that only users synced to Azure AD can authenticate. Set this to 1 in production — if set to 0, any AD user can authenticate even without MFA enrollment, which defeats the purpose.
Restart the NPS service to apply changes:
Restart-Service IAS
Open Security Group Rules for RADIUS Traffic
The NPS server needs to accept RADIUS traffic from the WorkSpaces directory. On the NPS server’s EC2 security group, add inbound rules:
aws ec2 authorize-security-group-ingress \
--group-id sg-0nps123456 \
--protocol udp \
--port 1812 \
--source-group sg-0directory789
aws ec2 authorize-security-group-ingress \
--group-id sg-0nps123456 \
--protocol udp \
--port 1813 \
--source-group sg-0directory789
| Port | Protocol | Purpose |
|---|---|---|
| 1812 | UDP | RADIUS Authentication |
| 1813 | UDP | RADIUS Accounting |
Also ensure the NPS server’s Windows Firewall allows these ports. The NPS role typically adds these rules automatically, but verify:
Get-NetFirewallRule | Where-Object { $_.DisplayName -like "*Network Policy Server*" } | Format-Table DisplayName, Enabled, Direction
Enable MFA on the AWS WorkSpaces Directory
Now connect WorkSpaces to your RADIUS server. You can do this via the console or CLI:
aws workspaces modify-workspace-creation-properties \
--resource-id d-0abc123456 \
--workspace-creation-properties \
EnableWorkDocs=false
Then configure the RADIUS settings on the directory:
aws ds enable-radius \
--directory-id d-0abc123456 \
--radius-settings '{
"RadiusServers": ["10.0.1.50"],
"RadiusPort": 1812,
"RadiusTimeout": 30,
"RadiusRetries": 3,
"SharedSecret": "your-shared-secret-from-step-2",
"AuthenticationProtocol": "PAP",
"DisplayLabel": "MFA Code",
"UseSameUsername": true
}'
Key settings explained:
| Parameter | Value | Why |
|---|---|---|
RadiusServers |
NPS server private IP(s) | Must be reachable from the directory’s VPC |
RadiusTimeout |
30 | Give users enough time to approve the push notification |
AuthenticationProtocol |
PAP | Required by the NPS extension for Azure MFA |
UseSameUsername |
true | Passes the AD username to NPS without modification |
Verify RADIUS Connectivity
Check the directory’s RADIUS status:
aws ds describe-directories \
--directory-ids d-0abc123456 \
--query "DirectoryDescriptions[0].RadiusSettings.RadiusStatus" \
--output text
The status should be Completed. If it shows Failed, check:
- NPS server is reachable from the directory subnet (test with
nc -zuv <nps-ip> 1812from an EC2 in the same subnet) - Shared secret matches exactly on both sides
- Windows Firewall on the NPS server isn’t blocking UDP 1812
Test the Full MFA Flow
Have a test user log into the WorkSpaces client:
- Open the Amazon WorkSpaces client
- Enter the registration code for your directory
- Enter the AD username and password
- User should receive a push notification on Microsoft Authenticator
- Approve the notification
- WorkSpaces session connects
If the authentication fails, check the NPS event logs on the Windows Server:
Get-WinEvent -LogName "Security" -FilterXPath "*[System[EventID=6272 or EventID=6273]]" -MaxEvents 10 | Format-List TimeCreated, Message
- Event ID 6272: Network Policy Server granted access (success)
- Event ID 6273: Network Policy Server denied access (failure — the message will tell you why)
Also check the Azure MFA extension logs:
Get-Content "C:\Program Files\Microsoft\AzureMfa\AuthZOptCh.log" -Tail 50
Roll Out to All Users
Once testing is confirmed working:
- Add all WorkSpaces users to the AD security group you specified in the NPS network policy
- Ensure all users have registered Microsoft Authenticator at https://aka.ms/mfasetup
- Communicate the change to users — the next time they log in, they’ll get a push notification
For users who haven’t enrolled in MFA yet, the authentication will fail. Set REQUIRE_USER_MATCH to 1 (Step 5) to enforce this, or temporarily set it to 0 during a migration period to allow unenrolled users through without MFA.
Set Up High Availability
In production, you should run two NPS servers in separate Availability Zones. Add both IPs to the RADIUS configuration:
aws ds enable-radius \
--directory-id d-0abc123456 \
--radius-settings '{
"RadiusServers": ["10.0.1.50", "10.0.2.50"],
"RadiusPort": 1812,
"RadiusTimeout": 30,
"RadiusRetries": 3,
"SharedSecret": "your-shared-secret",
"AuthenticationProtocol": "PAP",
"DisplayLabel": "MFA Code",
"UseSameUsername": true
}'
Both NPS servers need identical configurations — same RADIUS clients, same network policies, same NPS extension settings. WorkSpaces will failover automatically between the two.
Key Takeaway
The NPS extension for Azure MFA is the bridge that lets you use Microsoft Authenticator with AWS WorkSpaces without deploying a separate MFA infrastructure. The critical detail most people miss is that PAP must be used as the authentication protocol — both in the NPS network policy and in the WorkSpaces RADIUS configuration. This is counterintuitive because PAP sends passwords in cleartext, but the NPS extension needs the plaintext password to validate it against AD before triggering the MFA challenge. The RADIUS traffic between WorkSpaces and NPS stays within your VPC, so the cleartext password never crosses the public internet.
Have questions or need help with your WorkSpaces MFA setup? Connect with me on LinkedIn or X.