Tuesday, September 13, 2016

AD : Attempt to compromise security (HRESULT: 0x800704F1)

The full error is:

System.DirectoryServices.AccountManagement.PrincipalOperationException: The system detected a possible attempt to compromise security. Please ensure that you can contact the server that authenticated you. (Exception from HRESULT: 0x800704F1) ---> System.Runtime.InteropServices.COMException: The system detected a possible attempt to compromise security. Please ensure that you can contact the server that authenticated you. (Exception from HRESULT: 0x800704F1)

This is described here:

MS16-101: Description of the security update for Windows authentication methods

Essentially, the updates disable the ability of the Negotiate process to fall back to NTLM when Kerberos authentication fails for password change operation.

I found these useful:

Enabling Secure LDAP on Windows Server 2008/2012 Domain Controllers
Enabling Secure LDAP on Windows Server 2008/2012 Domain Controllers: Configuration

There is a good write-up here:

Solution for Problem in Change Password after Windows Security Update 

  • Enable LDAPS
  • Set "Trusted Hosts"
  • Revert the update
Only the former was an option for me.

And so began a journey into the depths of the Internet - or more specifically the huge amount of garbage, rubbish and misinformation out there :-(

One of the problems was the connection string.

I naively assumed that I simply needed to change:

LDAP://fqdn       to

But from what I can see, there is no actual protocol called LDAPS? It's official name is "Secure LDAP" and the connection string you need is:


The "correct" way to enable it is to install an Enterprise Root CA on a Domain Controller.

That wasn't an option (and a massive overkill) so I started wondering about installing a self-signed certificate on the DC.

Disclaimer: Using self-signed certificates or installing certificates as follows may not be the best solution security wise. Use this at your own risk!

The certificate that you need has to follow certain rules e.g.
  • It has to be for "Server Authentication" (OID:
  • The Subject name must match the Fully Qualified Domain Name (FQDN) of the host machine, such as Subject:CN=server.domain.com
  • (This is also true for the first name in the Subject Alternative Name (SAN))
  • The host machine account needs to have access to the private key
In other words, much the same as an IIS SSL certificate.

Once you have the .pfx file, and using "mmc" with:

Service Account / Local Computer

Select "Active Directory Domain Services".

and import.

You need this certificate in "NTDS\Personal" and  "NTDS\Trusted Root Certification Authorities".

To check this, you need to run "ldp" from the command line.

This should result in:

"Host supports SSL, SSL cipher strength = 256 bits"

If you need to run "ldp" from a non-DC machine, you need Remote Server Administration Tools (RSAT) for Windows Client and Windows Server.

Once "ldp" runs OK, you now have secure LDAP.

Now for the C# .NET side:

Replace the ldapConnection below:

DirectoryEntry ldapConnection = null;

      ldapConnection = new DirectoryEntry(LDAP fqdn, user, password);               
ldapConnection = new DirectoryEntry(LDAP fqdn, user, password, 
Coming at this from another angle, this code also worked:

Authenticating a user over LDAP in .Net: LdapConnection vs. PrincipalContext

Footnote: I also found that I could leave out the extra parameter:


if the user was "domain\user" rather than "user". Go figure!


Monday, September 12, 2016

OAuth2 : Verifying the ADFS JWT signature

I wrote up this post recently: OAuth2 : Verifying the Azure AD JWT signature.

So how do you do this with ADFS? You need ADFS 4.0 - Server 2016.

This has the following ADFS OAuth information ( ~ metadata) endpoints:

If we go to the "keys" endpoint, we see:

  "keys": [
      "kty": "RSA",
      "use": "sig",
      "alg": "RS256",
      "kid": "hHk-...A6k",
      "x5t": "hHk-...A6k",
      "n": "tGy...w9Q",
      "e": "AQAB",
      "x5c": [

The information under "x5c" is the certificate that you need.

As  per the linked post, you need to wrap this with "---BEGIN--- ---END---" and copy / paste and you'll see that the signing key is now verified.


Monday, September 05, 2016

B2C : The Process ID cannot be found for .NET Core exe

The .NET Core B2C sample is here.

I was helping to get it working on another Windows 10 box with VS 2015 when we got the error:

"The Process ID cannot be found for .NET Core exe".

Works fine on my Windows 8.1 box.

If we run .NET Core from the command line and then ran the project, it loaded but then localhost refused the connection.

So Mr. Google to the rescue and the vast majority of the suggestions were along the lines of:

"For me the problem was solved by closing down Visual Studio, deleting project.lock.json
and starting Visual Studio again"

That didn't help and neither did a whole lot of others.

Then I came across a reference along the lines of localhost certificates that aren't trusted for SSL.

And some bells started ringing because I hate IIS Express and don't use it but the Windows 10 machine did not have IIS installed so was running IIS Express by default.

(I always battle with IIS Express and SSL).

And the B2C sample uses https://localhost.

You need to trust the IIS Express self-signed certificate as per this post.

That fixed the problem.

How a trusted certificate issue caused an error message regarding a process ID is another issue entirely :-)


Friday, September 02, 2016

Postman : Using Postman for Confidential Grant on ADFS

Continuing the series for ADFS 4.0 on Server 2016.

The confidential flow relies on a client_id and a secret_key to authenticate the user.

The gist for the Postman collection is here.

You need to update your ADFS FQDN and the client_id and secret_key.

ADFS returns:

  "access_token": "eyJ...ErQ",
  "token_type": "bearer",
  "expires_in": 3600,
  "scope": "openid"

You can plug the access token into a JWT viewer.


Wednesday, August 31, 2016

Misc : Microsoft Open Specifications

Microsoft publishes a list of open specifications that enable inter-operability over here.

These include a number of specifications that describe ADFS and WAP (Web Application Proxy).

These include:
The MS-ADFSPIP document describes the interface between ADFS and WAP.

There are tons of questions on the forum around "Do I have to use WAP as the proxy. Can I use any reverse proxy or a load balancer or F5 or Netscaler etc. ?"

You can as long as the proxy you want to use implements the standards.

Good luck with getting your vendor to confirm that they do and to demonstrate this fact.

In addition, your vendor may also need to comply with the rules around

[MS-OFBA]: Office Forms Based Authentication Protocol

if e.g. the request is 
  • from a Microsoft Office application that relies on the Office Forms Based Authentication (OFBA) Protocol
  • from non-Microsoft-Office clients accessing services that implement the OFBA protocol [MS-OFBA] that rely on ADFS for authentication
It also needs to ensure that the correct claims are set e.g.


which is "True" is accessing ADFS directly or "False" if accessing via WAP.

My advice : Just use the WAP - much less stressful - :-).


Postman : Azure AD and Implicit Flow

I've been playing around with this and thought it would be worthwhile to document  the journey.

I have a web application in Azure AD and this application calls a web API.

The web application has permission to call the web API.

I want to use the implicit grant.

This is not supported OOTB :

AADSTS70005: response_type 'token' is not supported for the application

You need to update the manifest as per ADAL JS - response_type=“token” is not supported.

After sorting that out, my first call was:

https://login.microsoftonline.com/[tenant id]/oauth2/authorize?client_id=[client id]&response_type=token&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F

This resulted in:


OK - so I need a "resource" parameter - let's make it the same as the response type.

https://login.microsoftonline.com/[tenant id]/oauth2/authorize?client_id=[client id]&response_type=token&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F&resource=http%3A%2F%2Flocalhost%2Fmyapp%2F 

This resulted in:

http://localhost/myapp/#error=invalid_resource&error_description=AADSTS50001%3a+The+application+named+http%3a%2f%2flocalhost%2fmyapp%2f+was+not+found+in+the+tenant+named+[tenant id]/++This+can+happen+if+the+application+has+not+been+installed+by+the+administrator+of+the

So maybe I need the "APP ID URI" of the web application?

https://login.microsoftonline.com/[tenant id]/oauth2/authorize?client_id=[client id]&response_type=token&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F&resource=https://www.getpostman.com/oauth2/callback

This resulted in:

http://localhost/myapp/#error=invalid_request&error_description=AADSTS90027%3a+The+client+%[client id]%27+and+resource+%27https%3a%2f%2fwww.getpostman.com%2foauth2%2fcallback%27+identify+the+same+application...

Aha - so maybe I need the "APP ID URI" of the web API?

https://login.microsoftonline.com/[tenant id]/oauth2/authorize?client_id=[client id]&response_type=token&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F&resource=https://xxx.onmicrosoft.com/xxxService 

This resulted in:



I've obviously over-egged this a bit but you can see how you can work through the issues and figure out what's wrong based on the error messages.

The errors you get back from Azure AD  are an order of magnitude better than they used to be :-)

Note that the implicit grant does not return a refresh token because the browser has no means of keeping it private.


Friday, August 26, 2016

Misc : Creating self-signed certificates

I normally recommend SelfSSL7 but I was looking at Let's Encrypt which generates free CA SSL certificates.

This is in the context of Windows, specifically IIS SSL or securing ADFS.

To do this you need a client and one of the browser clients on the list was ZeroSSL.

If you click the Tools button, you'll see a "Self-Signed Certificate Generator".

There's a private key and a certificate.

Save the two files somewhere. If you save the certificate as a .cer file, you can double click on it and get the certificate wizard. You'll note that it has no private key which makes it useless for SSL. The certificate is valid for a year.

Now use OpenSSL to run:

openssl pkcs12 -export -out c:\xxx\adfs.pfx -inkey c:\xxx\zerossl.prv -in c:\xxx\zerossl.cer
Loading 'screen' into random state - done
Enter Export Password:
Verifying - Enter Export Password:

You'll need to pick a password.

Now if you double click on the .pfx file, the Import wizard will guide you as to installing it into the certificate store. You'll need to type in the password.

If you look at the "Enhanced Key Usage", you'll see it covers a lot of cases which is cool.


Postman : Using cURL to send OpenID Connect / OAuth to Azure AD / ADFS

"cURL is a computer software project providing a library and command-line tool for transferring data using various protocols".

I discovered that Postman allows you to generate these commands.

There are Postman collections for Azure AD / ADFS in gists as per Postman : Using Postman to get "Userinfo" on ADFS and the link inside the post.

So if you load the collection into Postman, click on "Generate Code" (top right) and then in the dropdown, select "cURL".


curl -k -X POST -H "Content-Type: application/x-
www-form-urlencoded" -H "Cache-Control: no-cache" -H "Postman-Token: 0303470d-5a
3b-bdea-9da3-9ab3e12f66ce" -d "client_id=37f...0b0e&scope=openid&redirect_uri=https://localhost:1234&grant_type=authorization_code&client_secret=Rel...G9&code=Nj...WWg" "https://my adfs/adfs/oauth2/token"



If you use self-signed certificates you need to use the "-k" option.


Thursday, August 25, 2016

Postman : Using Postman to get "Userinfo" on ADFS

This follows on from Postman : Using Postman to get "Userinfo" on Azure AD.

There's a ton of stuff on Azure AD but very little on ADFS.

The gist is here.

Same instructions as the Azure AD article.

In terms of configuring ADFS, have a look at ADFS - Web App and Web API on Server 2016 TP4 ADFS 4.0 . You only need to do the Web App. part.


Wednesday, August 24, 2016

Postman : Using Postman to get "Userinfo" on Azure AD

I got this idea from v2.0 Protocols - OAuth 2.0 Authorization Code Flow that has "Run in Postman" buttons that load Postman collections.

So I made my own which you can find in this gist.

This uses OpenID Connect / OAuth 2.0.

It has three steps.

The first you have to customise for your clientID etc. and then run in a browser.

Then copy / paste the code from the reply into the second, customise for your clientID etc. and click "Run".

This returns an access token, an ID token and a refresh token.

(You can see what's in them by copy / paste the access / ID token into jwt.io).

The code inside the collection automatically sets up the token for the third step so all you have to do is press "Run".

You will see the full "Userinfo".

There are full instructions in the collection.


Thursday, August 18, 2016

OAuth2 - Testing OpenID Connect / OAuth 2.0

Utilities to help you develop using OpenID Connect and OAuth 2.0 are always useful so I've listed out the ones I know about.

Postman - Really useful to for API testing. Requires Chrome.

v2.0 Protocols - OAuth 2.0 Authorization Code Flow - Article that has links to Postman collection to try this out step by step. Azure AD centric.

Inspecting the JWT token - from Auth0.

Outlook OAuth Sandbox - for testing Outlook.Office.com API.

OpenID Connect Playground - from Auth0 - for developers to test and work with OpenID Connect calls.

Demo. instance of IdentityServer - has full stack OIDC / OAuth2 support.

Tying the two together - hooking the playground up with IdentityServer.