VMware Horizon True SSO with UAG SAML

Last Modified: Apr 26, 2023 @ 9:38 am



To configure SAML on Unified Access Gateway (UAG), you must have the following versions:

  • UAG 3.8 or newer
  • Connection Servers 7.11 or newer
  • For Windows 10 version 2004, deploy Horizon 2103 (8.2) or newer.

True SSO is optional.

  • SAML does not provide the user’s password to Horizon, which means that Horizon cannot perform single sign-on to the Horizon Agent machine and thus the Horizon Agent machine will prompt the user to login again. This usually means the user has to login twice.
  • To eliminate the second logon on the Horizon Agent machine, implement True SSO, which generates certificates for each user and then uses those certificates to automatically sign into the Horizon Agent machine.

Horizon Enrollment Servers ask Microsoft Certificate Authority servers to generate the SSO certificates for each user. This is an identity operation and thus the Horizon Enrollment Servers should be treated like Domain Controllers.

  • The Horizon Enrollment Server software must be installed on standalone servers (no other Horizon components).
  • For High Availability you can build two Horizon Enrollment Servers.

When you use Horizon Client to connect to a UAG that is SAML-enabled:

  1. It opens the default browser and prompts the user to sign into your SAML Identity Provider. If the user is already signed in then the user won’t see any sign-in prompt.
  2. After sign-in, the browser will then prompt the user to open VMware Horizon Client.
  3. If the user locks the desktop then the user will need to know the local Active Directory password to unlock it.

Certificate Authority

Horizon Enrollment Servers can use a Microsoft Certificate Authority that already exists. Or you can install Microsoft Certificate Authority on the Horizon Enrollment Servers. If you have two Enrollment Servers, then install Microsoft Certificate Authority on both of the servers.

  1. Install Microsoft Certificate Authority from Server Manager > Manage > Add Roles and Features.
  2. Select Active Directory Certificate Services.
  3. The only Role Service needed for True SSO is Certification Authority.

The Microsoft Certificate Authority must be an Enterprise CA.

  1. After role installation, click the flag icon and then click the link to Configure Active Directory Certificate Services.
  2. In the Setup Type page, select Enterprise CA.
  3. In the CA Type page, if you already have a Root CA, then you can select Subordinate CA. Otherwise, you need at least one Root CA in your environment.

After Microsoft CA is installed, run the following commands:

certutil -setreg ca\CRLFlags +CRLF_REVCHECK_IGNORE_OFFLINE
sc stop certsvc
sc start certsvc

If you just built a new Certificate Authority server then True SSO won’t work until you run gpupdate /force on all of your Domain Controllers and Horizon Agent machines. Or wait several hours for group policy to update.

Certificate Template

  1. On the Certificate Authority machine, from Start Menu, run Certification Authority.
  2. Right-click the Certificate Templates node and click Manage.
  3. Right-click the Smartcard Logon template and click Duplicate Template.
  4. On the Compatibility tab, change the drop-down for Certification Authority to Windows Server 2008 R2.
  5. Change the drop-down for Certificate recipient to Windows 7 / Server 2008 R2.
  6. On the General tab, name it True SSO or similar.
  7. Change the Validity Period to 1 day or similar.
  8. On the Request Handling tab, change the drop-down for Purpose to Signature and smartcard logon.
  9. Check the box next to For automatic renewal of smart card certificates, use the existing key if a new key cannot be created.
  10. On the Cryptography tab, change the drop-down for Provider Category to Key Storage Provider.
  11. On the Server tab, check the top box for Do not store certificates and requests in the CA database.
  12. Uncheck the bottom box for Do not include revocation information in issued certificates.
  13. On the Issuance Requirements tab, check the box next to This number of authorized signatures and enter 1 as the value.
  14. Change the drop-down for Policy type required in signature to Application policy.
  15. Change the drop-down for Application policy to Certificate Request Agent.
  16. At the bottom, change the selection to Valid existing certificate.
  17. On the Security tab, add your Horizon Enrollment Servers computer objects. This can be an AD group instead of individual servers.
  18. For each Enrollment Server computer object, on the bottom, check the Allow box for the Enroll permission. Click OK when done.
  19. Back in the Certificate Templates Console, right-click the Enrollment Agent (Computer) template and click Properties.
  20. On the Security tab, add your Horizon Enrollment Servers computer objects. This can be an AD group instead of individual servers.
  21. For each Enrollment Server computer object, on the bottom, check the Allow box for the Enroll permission. Click OK when done.
  22. Close the Certificate Templates Console.
  23. Back in the Certification Authority Console, with Certificate Templates highlighted on the left, if your environment has multiple CAs but this CA is dedicated to True SSO, then delete all templates from the right. Note: Domain Controllers must have certificates installed so make sure you have at least one other CA that is issuing Domain Controller certificates.
  24. Right-click Certificate Templates and click New > Certificate Template to Issue.
  25. Select Enrollment Agent (Computer) and click OK.
  26. Issue another certificate template but this time select the True SSO template.
  27. Your CA should now show the two templates.
  28. If you have a second CA, and if it is dedicated to True SSO, then delete all templates from that CA. Then configure it to issue the same two templates.

Enrollment Server

Horizon Enrollment Server must be installed on dedicated machine(s) that don’t have any other Horizon components installed.

  1. Login to the new Horizon Enrollment Server that has at least 4 GB of RAM.
  2. Run certlm.msc.
  3. Expand Personal, then right-click Certificates, expand All Tasks, and click Request New Certificate.

    1. In the Before You Begin page, click Next.
    2. In the Select Certificate Enrollment Policy page, click Next.
    3. In the Request Certificates page, check the box next to Enrollment Agent (Computer) and then click Enroll.
    4. In the Certificate Installation Results page, click Finish.
    5. Notice the expiration date on the Enrollment Agent certificate. Make sure you renew it before it expires.
  4. Go to the downloaded Horizon software and run VMware-Horizon-Connection-Server-x86_x64.exe.
  5. In the Welcome to the Installation Wizard for VMware Horizon Connection Server page, click Next.
  6. In the License Agreement page, select I accept the terms in the license agreement and click Next.
  7. In the Destination Folder page, click Next.
  8. In the Installation Options page, change the selection to Horizon Enrollment Server and click Next.
  9. In the Firewall Configuration page, click Next.
  10. In the Ready to Install the Program page, click Install.
  11. In the Installer Completed page, click Finish.
  12. If Microsoft CA is installed on the Enrollment Server, then run regedit.
    1. Go to HKLM\Software\VMware, Inc.\VMware VDM.
    2. Create a new Key named Enrollment Service.
    3. Under Enrollment Service, create a new String (REG_SZ) value named PreferLocalCa and set it to 1.
    4. Also add string values for UseKerberosAuthenticationToCa = false and UseNTLMAuthenticationToCa = true
  13. If you have two Enrollment Servers, then repeat this entire section on the other server. This includes requesting the Enrollment Agent certificate, installing the Enrollment Server software, and setting the PreferLocalCa registry value.


  1. Log in to a Connection Server and run certlm.msc.
  2. On the left, expand VMware Horizon View Certificates and then click Certificates.
  3. On the right, find the certificate with the Friendly Name vdm.ec, right-click it, expand All Tasks, and then click Export. All Connection Servers have the same certificate so you only need to export from one of the Connection Servers.
  4. In the Export Private Key page, select No, do not export the private key, and then click Next.
  5. In the Export File Format page, leave it set to DER, and then click Next.
  6. Save the certificate to a file that you can access from your Enrollment Server(s).
  7. Log in to an Enrollment Server and run certlm.msc.
  8. On the left, right-click VMware Horizon View Enrollment Server Trusted Roots, expand All Tasks, and click Import.
  9. In the Welcome to the Certificate Import Wizard page, click Next.
  10. In the File to Import page, browse to the certificate that you exported from the Connection Server and then click Next.
  11. In the Certificate Store page, VMware Horizon View Enrollment Server Trusted Roots should already be selected so just click Next.
  12. In the Completing the Certificate Import Wizard page, click Finish.
  13. Repeat the certificate import process on the other Horizon Enrollment Server.


  1. Login to your SAML Identity Provider (IdP) and create an application for Unified Access Gateway.
  2. For Okta, see VMware Tech Zone.
  3. Azure AD has a gallery application to make configuration easier. Or use the following values:
    • Identifier = https://*.HORIZON_UAG_FQDN.com/portal
    • Reply URL (Assertion Consume Service URL = https://<HORIZON_UAG_FQDN>/portal/samlsso
  4. When done, it should look something like this:
  5. Download the Federation Metadata XML from your Identity Provider. The Metadata Url doesn’t seem to work.
  6. Login to your UAG admin page (https://<HORIZON_UAG_FQDN>:9443/admin).
  7. Select Configure Manually.
  8. Scroll down to the section named Identity Bridging Settings and click Upload Identity Provider Metadata.
  9. Click Select in the IDP Metadata row.
  10. Browse to the .xml file and then click Save.
  11. At the top of the page, next to Edge Service Settings click SHOW.
  12. Next to Horizon Settings click the gear icon.
  13. At the bottom of the page, click More.
  14. At the top of the page, change the drop-down for Auth Methods to SAML.
  15. Change the drop-down for Identity Provider to the SAML Identifier in the Metadata that you just imported.
  16. At the bottom of the page click Save.
  17. Login to Horizon Console.
  18. In the left menu, go to Settings > Servers.
  19. On the right, click the tab named Connection Servers.
  20. Highlight a Connection Server that UAG talks to and click Edit.
  21. Switch to the tab named Authentication.
  22. Change the drop-down for Delegation of Authentication to VMware Horizon (SAML 2.0 Authenticator) to Allowed.
  23. Click the button named Manage SAML Authenticators.
  24. Click Add.
  25. Change the selection for Type to Static. Dynamic seems to only be valid for VMware Access (aka Identity Manager).
  26. Go to your Metadata .xml file and edit it with a text editor. Then copy its contents to your clipboard.
  27. Back in Horizon Console, in the SAML Metadata field, paste in the contents.
  28. Give your SAML 2.0 Authenticator a name and click OK.
  29. Click OK to close the Manage SAML Authenticators window.
  30. Edit other Connection Servers that UAG talks to and go to the Authentication tab.
  31. Set SAML 2.0 Authenticator to Allowed and then click the Manage SAML Authenticators button.
  32. The previously created SAML Authenticator should already be there so just click Edit.
  33. At the bottom, check the box next to Enabled for Connection Server and then click OK. Repeat on any other Connection Server that UAG talks to.
  34. In Horizon Console, if you go to Monitor > Dashboard and then click VIEW in the System Health section.
  35. On the left go to Other Components. On the right go to the tab named SAML 2.0. You should see your SAML Authenticator.

Enable True SSO

Login to one of the Connection Servers and open a Command Prompt as administrator. The commands in this section have case sensitive parameter names. These commands are vdmutil, not vdmadmin.

Run the following command to add each Enrollment Server. Notes:

  • For the --authPassword fields, you enter "*" (with quotes) to be prompted to enter the password instead of specifying it at the command line.
  • --authAs fields do not include the domain name since domain is a different field.
vdmUtil --authAs admin-username --authDomain domain-name --authPassword admin-user-password --truesso --environment --add --enrollmentServer enroll-server1-fqdn,enroll-server2-fqdn

Run the following command to see the available certificate authorities and certificate templates for a particular domain.

vdmUtil --authAs admin-username --authDomain domain-name --authPassword admin-user-password --truesso --environment --list --enrollmentServer enroll-server-fqdn --domain domain-fqdn

Run the following command to enable the Enrollment Servers for a particular domain. This syntax configures the Enrollment Servers as active/passive (failover). Note: certificateServer is the CA name from the previous command and not the server’s FQDN.

vdmUtil --authAs admin-username --authDomain domain-name --authPassword admin-user-password --truesso --create --connector --domain domain-fqdn --template TrueSSO-template-name --primaryEnrollmentServer enroll-server-fqdn --secondaryEnrollmentServer enroll-server-fqdn --certificateServer ca1-common-name1,ca2-common-name --mode enabled

Run the following command to see the SAML Authenticators configured in Horizon Console.

vdmUtil --authAs admin-username --authDomain domain-name --authPassword admin-user-password --truesso --list --authenticator

Run the following command to enable True SSO for a particular SAML Authenticator. Enter either ENALBED or ALWAYS.

vdmUtil --authAs admin-username --authDomain domain-name --authPassword admin-user-password --truesso --authenticator --edit --name authenticator-name --truessoMode {ENABLED|ALWAYS}

For more info, see Command-line Reference for Configuring True SSO at VMware Docs.

If you prefer to load balance your Enrollment Servers instead of active/passive, do the following:

  1. On a Connection Server, run adsiedit.msc.
  2. Change the Connection Point to dc=vdi,dc=vmware,dc=int.
  3. Change the Computer to localhost and then click OK.
  4. On the left, expand Properties, and then click Global.
  5. On the right, double-click Common.
  6. Find pae-NameValuePair in the list and Edit it.
  7. Enter cs-view-certsso-enable-es-loadbalance=true and then click Add.
  8. Click OK a couple times to close everything.

You can view the status of True SSO in Horizon Console.

  1. In Horizon Console, go to Monitor > Dashboard and on the right, in the System Health section, click VIEW.
  2. With Components selected on the left, on the right is a tab named TrueSSO.

162 thoughts on “VMware Horizon True SSO with UAG SAML”

  1. Hi

    I suddently getting access denied errors truesso authentication

    if run es dig following out put but this work fine on connection server

    EnrollmentInterface::SendMsgToEnrollmentPlugin(SubmitRequest) begin
    Call to CertEnroll failed: Failed to locate a connected CA – ErrorCode = 2147944650 (0x00000000800708CA), 1
    EnrollmentInterface::SendMsgToEnrollmentPlugin(SubmitRequest) end
    SubmitRequest Failed
    Response ErrorCode = “-2147022646”
    ErrorText = “Failed to locate a connected CA”
    FailureReason = “SubmitFailureMayRetry”

    C:\Temp>es_diag.exe /enrollmenttest /esNAme:CPT2ENVM01 /certauth /domain:am.tsacorp.com /caserver:COV1CER03VM /requester:am\myuser /template:TrueSSO /LogToScreen
    Execute EnrollmentDiags::EnrollmentTest:
    Connect to the Enrollment Service: CPT2ENVM01
    2023-09-27T12:32:13.458+02:00 WARN (03F0-1B00) [es_diag] CERTSSL: Unable to open certificate store VMware Horizon View Certificates, error=5 (Access is denied.)
    2023-09-27T12:32:13.458+02:00 WARN (03F0-1B00) [es_diag] ConnectChannelByCertSsl cert not found
    Failed to connect channel: certificaste auth failed
    Failed to connect a channel to the Enrollment Service.
    The Certificate used to Authenticate to the ES may not be trusted.
    For more information please see the Horizon View log-file on this system and on the Horizon View Enrollment Server.

  2. Hi

    Thanks using you article , I successfully setup UAG and TrueSSO in POC setup.

    I had one query regarding same, I had 3 sites in different geographic location where around 700 + VDIs each sites and each have 3 different set LB and Connection Brokers. I know and VMware says we need different UAGs and enrollment servers for each site/setup. Can I used same True SSO and Enrollment agent certificate which I created for POC setup or need create three different templates for each sites. I can publish to locate CA to avoid delay of authentication

    1. I think that will work. Just add the Connection Server cert from each pod to the Enrollment Servers. Also run the vdmutil commands on each pod.

  3. Hi Carl,
    i enabled truesso in my environment and everything appears green in horizon and uag admin portals. I can connect to my uag via the horizon client and it gives me all the pools im entitled to but when i click on a pool it immediately tells me access denied. When i check the connection server logs I see “ERROR (1E80-07FC) [ESConnectionManager] CertSso: Certificate generation request failed … Error: 258, ErrorText: The Request timed out, Reason: (258), EsReason: SubmitFailureMayRetry”. My enrollment server is also my CA and i have the registry files to prefer local CA. I can telnet to port 32111 from the connection server to enrollment server

    Any help is appreciated!

      1. the failed requests in CA console is empty but i checked the logs of the enrollment server and i see this
        “MessageFrameWorkDispatch> [wsnm_certenroll] EnrollmentServices::SubmitRequest(): The Request timed out – ErrorCode = 258 (0x0000000000000102)
        2023-08-28T10:00:18.953-04:00 ERROR (056C-0818) [wsnm_certenroll] CertEnrollService::CertEnrollOperation::SubmitRequestHandler(): The Request timed out – ErrorCode = 258 (0x0000000000000102)
        2023-08-28T10:00:27.191-04:00 WARN (056C-0A78) [wsnm_certenroll] CertificateServer::Submit(): Request to was successful but slow – 33250 ms”

  4. Hi gents, I have a question: I have Horizon 7.13 installed as no FIPS mode. And I need to know if my linux desktops could have FIPS mode enabled and SSO will works? Somdoby knows if this configuration is possible?

  5. I’m struggling with the True SSO w/Horizon (not workspace one) passing through to the desktop. I get two different errors.
    The attempted logon is invalid. This is due to a bad username or authentication information. An untrusted certificate authority was detected while processing the domain controller certificate used for authentication.
    The client has failed to validate the domain controller certificate for serverFQDN. The following error was returned from the certificate validation process: A certification chain processed correctly, but one of the CA certificates is not trusted by the policy provider.

    The es_diag tool lets me create a cert that looks valid and is signed by our internal MS CA. The chain goes root, sub, cert, and it all looks good. If I remove the domain controller authentication template from the domain controller. Yubikey logon works fine with certs signed by the same local CA and smart card logon on a physical PC. I’m not turning up many results for fixes and VMware support has been very slow. If anyone has seen this please reply.

    1. I finally found the issue.

      We have certificates set to auto enroll and the only reason we use those certs is for wireless access. At one point we were rolling certs out like it was nobody’s business when VDIs would spin up and reboot, so we turned off the auto enroll GPO for the VDI environment.

      This left our enterprise trust blank in “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\EnterpriseCertificates\NTAuth\Certificates”

      I ended up adding a powershell script to the end of our onboarding postsync VDI script to include adding our Cas

      “certutil -enterprise -addstore NTAuth CAFile.cer”

      It appears disabling autoenroll breaks this and I only really stumbled on it by chance. The certs were in the appropriate places (trusted roots, etc) if you were looking in certlm.msc.


  6. Hi Carl,
    I appreciate all that you do. I’ve been banging my head against this issue for a while now and every time I find someone else with the issue, the thread just dies, without a resolution.

    Our SSO through Azure is working, but like others, we are prompted to log in again to the VDI machine. It’s not actually doing the true SSO. In the CS, everything is green. I’ve run es_diag.exe /enrollmenttest and /testlogon and both come back successful.

    Enrollment Test
    C:\TEMP>es_diag.exe /enrollmenttest /esname:xxxx-01 /certauth /domain:xxxxxx.edu /requester:xxxxxx /template:TrueSSOCert /caserver:xxxxx-01-CA /certFile:TestCert
    Execute EnrollmentDiags::EnrollmentTest:
    Connect to the Enrollment Service: xxxxx-01
    Successfully connected to the Enrollment Server
    Configure the enrollment service for the selected domain
    Wait up to 30 seconds for the Active Directory to be read
    Send Cert-Request(s) to the enrollment service:
    Successfully requested a Certificate

    Requested : 1, Issued: 1, Failed: 0, Retry: 0
    Total Time: 0.023 sec to generate 1 certificates.
    Throughput: 43 certificates/second.
    Average : 0.023 sec to generate a certificate.

    Subject : dxxxxx
    UPN : dxxxxx@xxxxxx.edu
    SerialNo : 1B:00:00:00:05:EA:38:40:51:A3:3E:50:64:00:00:00:00:00:05
    UTC Time : 2023-06-07,14:42:57
    Valid From: 2023-06-07,14:32:57
    Valid To : 2023-06-08,02:32:57
    Validity : Certificate is valid
    Saved Certificate to file

    TestLogon (not /logontest)
    C:\TEMP>es_diag.exe /enrollmenttest /testlogon /esname:xxxxx-01 /certauth /domain:xxxx.edu /requester:xxxxx /template:TrueSSOCert /caserver:xxxxxx-01-CA /certfile:testcert
    Execute EnrollmentDiags::EnrollmentTest:
    Connect to the Enrollment Service: xxxxxxx-01
    Successfully connected to the Enrollment Server
    Configure the enrollment service for the selected domain
    Wait up to 30 seconds for the Active Directory to be read
    Send Cert-Request(s) to the enrollment service:
    Successfully requested a Certificate

    Requested : 1, Issued: 1, Failed: 0, Retry: 0
    Total Time: 0.139 sec to generate 1 certificates.
    Throughput: 7 certificates/second.
    Average : 0.139 sec to generate a certificate.

    Subject : dxxxxxx
    UPN : dxxxxxx@xxxxxx.edu
    SerialNo : 1B:00:00:00:06:9F:77:29:EA:F0:34:CB:54:00:00:00:00:00:06
    UTC Time : 2023-06-07,14:46:59
    Valid From: 2023-06-07,14:36:59
    Valid To : 2023-06-08,02:36:59
    Validity : Certificate is valid
    Attempting S4U X.509 Certificate logon
    Successfully performed S4U X.509 Certificate logon
    Saved Certificate to file

    In GPO I’ve set Windows Components/Remote Desktop Services/Remote Desktop Session Host/Security “Always prompt for password upon connection” to Disabled
    I’ve also set Local Policies/Security Options/Interactive Logon “Interactive logon: Do not require CTRL+ALT+DEL” to Enabled

    We’re between semesters, but people are still using VDI, so this is all going through a test UAG so I don’t impact production.

    Any suggestions other than blowing it all out and starting from scratch again?


      1. Hi Carl,
        Thanks for that! For my test user, I was getting an error KDC_ERR_WRONG_REALM.

        Unfortunately, we had an architect that decided we had to have a root domain and multiple sub-domains(Staff, Students, Student Computers, etc)…Our plan is to flatten the domain, so all VDI was put on the root domain. So, only root domain users will be in the correct realm and get TrueSSO. I just tested successfully with my root domain test user.

        So I guess, now we have to decide if we’re gonna spread our VDI out throughout all of the subdomains. Unless there’s a way to pull the realm based on the Users domain…

        1. One forest? Or multiple forests? If multiple forests, is UPN suffix routing configured on the trust?

          I would have expected that Windows can traverse the trusts to find the user by UPN but maybe not.

          1. It’s a single forest. I’m looking into cross-realm trusts right now. It’s possible that whoever set all this up disabled it.

            I really appreciate how responsive you are and everything you are doing for the community!

          2. I finally see that when this was set up, they did not enable “The other domain supports Kerberos AES encryption”. I’ve requested a change in this for testing.

          3. Hi Carl,
            I finally figured it out. VMware does have a trueSSO architecture document


            This states that you need a CA on each domain/subdomain. I set this up, but this only worked for one sub domain (staff.xxx.edu). The student sub domain still didn’t work. The problem was the fqdn is student.xxx.edu while their email address is my.xxx.edu.

            I ended up modifying the TrueSSO Cert template to “Include email name in subject name” in the Subject Name tab. Now it seems to be working for all users.

            Thanks again for your help!

Leave a Reply

Your email address will not be published. Required fields are marked *