Active Directory, ADFS, Certificates, Troubleshooting, WAP, Web

Getting Event ID 144 On Your Web Application Proxy When Trying To Connect To ADFS?

Perhaps as you were setting up your brand new shiny 2012 R2 Web Application Proxy (WAP) to connect to your 2012 R2 Active Directory Federation Services (ADFS 3.0) server you ran into a 404 error in the web browser followed by this error message in the event viewer logs when trying to do your idpinitiated sign on test from the internet using the WAP DNS URL:

Event ID 144

The Federation Service Proxy blocked an illegitimate request made by a client, as there was no matching endpoint registered at the proxy.

Huh?!?!? Okay, so here is one of the reasons why it is generating: the root part of your DNS you use at the proxy must match the DNS you have on your internal ADFS server.

For example, if you configured your internal federation service name to be different (adfs.internaldomain.com) than the web application proxy name (adfs.yourexternalweb.com) then when the proxy tries to interpret the request it sees the mismatching DNS as an illegitimate request, thus blocking it. And while the WAP will publish various web applications that have different DNS this does not cover the initial configuration of the WAP when it is initially pointed to the internal ADFS server.

So what’s the solution?

Get a DNS entry on your internal domain to point to your internal ADFS server using what you used for the web application proxy. These names MUST match for the WAP to work. If you cannot get a DNS entry on your internal domain to match the DNS on the external domain then my recommendation would be to use your etc/hosts file to point your proxy to your ADFS server.

Once you have the DNS entry or etc/hosts entry in place for your WAP and ADFS server then do the following:

1. Put the adfs.yourexternalweb.com public cert (with private key) on the ADFS server to be used for communications.
2. (Assuming ADFS has already been configured) Remove the adfs role from the ADFS server and do not save the databases and reboot.
4. Install the ADFS role with the new matching Federation Service name (adfs.yourexternalweb.com). Make sure to point to the newly installed certificate. Do not utilize old database information. Create a new WID database.
5. Remove the WAP role from the WAP server.
6. Reboot.
7. Reinstall WAP role and Configure. Once post deployment has completed successfully do NOT create an app for ADFS as it is automatically publishing ADFS as a proxy under the covers.

Hope this helps. Questions are welcome.

Active Directory, C#, Certificates, Programming

Programmatically Install A Root CA Certificate So Users Don’t Have To (C#)

So here’s the backstory: I received the task of improving certificate enrollment so that users can

1) Be verified via username, password, captcha & verification pin

2) Auto Enroll without an external approval

3) Simplify the process

As some of you already know, ADCS via web enrollment is…how can we say…dated. So I wrote an application that sits in front of ADCS to first verify the user. Once they are through then the web enrollment is configured to let them run the wizard through to installing their cert. The issue that came to me is that most end-users will not take the time to ensure the root CA makes it to the trusted store (thus giving the classic CA cert is not installed message). So I received the order from on-high to “do it for them”. At first I struggled, attempting to understand how this could be done. I spoke with Microsoft and as I already was aware they indicated that having the user choose the trusted root store for the CA is by design. So what to do…ah I know, let’s just script it out.

So this is as simple as it gets. Download the cert, store it on the local drive and use the built-in certmgr.exe to perform the root CA to trusted store installation. Here it is (this code is just one a basic console app):

Code:

using System.Security.Cryptography.X509Certificates;

WebClient webClient = new WebClient();
webClient.DownloadFile("https://yourserver.domain.com/CertSrv/certnew.cer?ReqID=CACert&Renewal=0&Mode=inst&Enc=b64", @"C:\Temp\certnew.cer");

X509Store store = new X509Store(StoreName.Root,
StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadWrite);
X509Certificate2Collection collection = new X509Certificate2Collection();
X509Certificate2 cert = new X509Certificate2(@"C:\Temp\certnew.cer");
byte[] encodedCert = cert.GetRawCertData();
Console.WriteLine("We are now installing the CA certificate into the Trusted Root Certificate store ...");
store.Add(cert);
Console.WriteLine("Done! The CA certificate was successfully. Press any key to close.");
Console.ReadKey();
store.Close();

This finishes the root CA portion so they can fly through the rest of web enrollment. Hope this helps.