How to Securely Embed AD Credentials in RemoteApp .RDP Files for Domain-Independent SaaS Access


2 views

When implementing RemoteApp in Windows Server 2008 R2 environments for SaaS delivery, we often face authentication challenges with external clients. The core problem emerges when:

  • Client workstations reside in untrusted domains
  • VPN connectivity exists but domain trust isn't feasible
  • End applications have their own authentication layers
  • AD account management becomes an unnecessary burden

Standard .rdp files connect to RemoteApp with these parameters:

full address:s:rdshost.yourdomain.com
remoteapplicationmode:i:1
remoteapplicationname:s:YourERPApp
remoteapplicationprogram:s:||ERPClient

While .rdp files support password storage via:

username:s:service_account
password 51:b:01000000D08C9D...[truncated]

This approach has significant security limitations:

  • Passwords are encrypted with weak protection (DPAPI)
  • File distribution becomes sensitive
  • No automatic rotation capabilities

Option 1: Restricted Service Accounts

Create a limited AD account with:

# PowerShell: Create restricted account
New-ADUser -Name "ERP_Gateway" -AccountPassword (ConvertTo-SecureString "ComplexP@ssw0rd!" -AsPlainText -Force)
Set-ADUser -Identity "ERP_Gateway" -PasswordNeverExpires $true
Set-ADUser -Identity "ERP_Gateway" -LogonWorkstations "WORKSTATION1,WORKSTATION2"

Option 2: Certificate-Based Authentication

Configure RDS for smart card auth and use certificates:

# RDP file addition:
enablecredsspsupport:i:0
authentication level:i:2
smartcard:i:1

Option 3: RD Gateway with CAP/RAP Policies

Implement granular access control:

# Sample CAP policy:
New-RDCAP -Name "ERP_Users" -UserGroups "DOMAIN\ERP_Gateway" -AuthMethod 1

When implementing any credential storage solution:

  • Always set appropriate NTFS permissions on .rdp files
  • Consider using Group Policy Preferences for secure distribution
  • Monitor authentication events in Security logs
  • Implement account lockout policies for service accounts

Here's a PowerShell script to generate secure .rdp files:

function New-SecureRDPFile {
    param(
        [string]$Server,
        [string]$AppName,
        [string]$Username,
        [string]$Password
    )
    
    $content = @"
full address:s:$Server
remoteapplicationmode:i:1
remoteapplicationname:s:$AppName
username:s:$Username
"@
    
    # Requires Windows Security assembly
    Add-Type -AssemblyName System.Security
    $encrypted = [System.Security.Cryptography.ProtectedData]::Protect(
        [System.Text.Encoding]::Unicode.GetBytes($Password),
        $null,
        [System.Security.Cryptography.DataProtectionScope]::CurrentUser)
    
    $content += "password 51:b:" + [System.Convert]::ToBase64String($encrypted)
    return $content
}

When deploying RemoteApp in cross-domain scenarios, the authentication prompt creates friction for end users. The fundamental issue is that Remote Desktop Services (RDS) requires Windows authentication before launching the RemoteApp, even when the target application has its own security layer.

Before exploring solutions, let's outline the non-negotiable requirements:

  • No domain trust relationship exists (or will exist)
  • VPN connectivity is already secured
  • ERP application handles its own authentication
  • AD credential management is undesirable for end users

While directly embedding credentials in .rdp files is discouraged for security reasons, we can implement a secure alternative using these .rdp parameters:

full address:s:yourRDSserver.domain.com
alternate full address:s:yourRDSserver.domain.com
remoteapplicationmode:i:1
remoteapplicationname:s:YourAppName
remoteapplicationprogram:s:||YourPublishedApp
remoteapplicationcmdline:s:
disableconnectionsharing:i:1
authentication level:i:2
prompt for credentials:i:0
promptcredentialonce:i:1

Create a dedicated low-privilege service account in AD specifically for RemoteApp access. Then configure the connection to use these credentials transparently:

// PowerShell script to generate pre-authenticated .rdp files
$RDPParams = @{
    "full address" = "yourRDSserver.domain.com"
    "remoteapplicationname" = "YourAppName"
    "authentication level" = "2"
    "promptcredentialonce" = "1"
}

$RDPContent = $RDPParams.GetEnumerator() | ForEach-Object {
    "$($_.Key):$($_.Value[0]):$($_.Value[1])"
}

$RDPContent | Out-File -FilePath "C:\path\to\your\app.rdp" -Encoding ascii

When implementing this solution:

  • Set the service account password to never expire
  • Apply minimal required permissions via Group Policy
  • Consider implementing IP restrictions for the service account
  • Regularly audit service account usage

For enhanced security, implement an RD Web Access front-end with pre-authentication:

<!-- Sample HTML form for credential injection -->
<form action="https://rdweb.domain.com/RemoteApp/" method="post">
    <input type="hidden" name="RemoteApplicationName" value="YourApp" />
    <input type="hidden" name="DomainUserName" value="SVC_RemoteApp" />
    <input type="hidden" name="DomainUserPassword" value="[ENCRYPTED]" />
    <button type="submit">Launch Application</button>
</form>

Implement these PowerShell commands for ongoing management:

# Check active RemoteApp sessions
Get-RDUserSession -ConnectionBroker "yourRDSserver.domain.com"

# Monitor service account usage
Get-WinEvent -LogName "Security" -FilterXPath "*[System[EventID=4624]]" | 
Where-Object {$_.Properties[5].Value -eq "SVC_RemoteApp"}