Wednesday, September 07, 2016

MSMQ, WCF and IIS: Getting them to play nice: The extras, Part II

Here's another catch I've found that causes issues when trying to set up a 3-party queueing system: You need to log on interactively as the user that's accessing the queues on each of the machines where it's accessing the queues! This is so that a certificate can get created for the user on those machines to be used with Active Directory authentication.

Tuesday, September 06, 2016

Solving "m_safeCertContext is an invalid handle."

I've recently been trying to get an application working in Azure App Service that acts as a client who calls out to another service via WCF with TransportWithMessageCredential mode for security and Certificate mode for authentication. I've been getting the following error:

m_safeCertContext is an invalid handle.

According to this blog post, this error gets thrown when the certificate isn't correctly imported or has incorrect trust (for any of many possible reasons). Some of those reasons can include incorrect passwords, but there are others as well, like what I was encountering: in Azure App Service, there's no local user signed on when your application is running. Because of that, you run afoul of a subtle issue with managing certificates: all of the constructors, by default, use the user certificate store to temporarily store the PrivateKey of any loaded X509Certificate2 objects. Therefore, on an Azure App Service application, unless you use the new X509Certificate2(certBytes, passwordString, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable) constructor with the MachineKeySet | Exportable flags, your certificate will not be correctly read and will SILENTLY FAIL!!

Friday, September 02, 2016

Solving 'The remote certificate is invalid according to the validation procedure' with WCF channels

This typically happens most often (when using certificates) when the certificate Common Name (CN) doesn't match the DNS host name of the server.

Solving "Binding validation failed because the binding's MsmqAuthenticationMode property is set to WindowsDomain but MSMQ is installed with Active Directory integration disabled"

I've been trying to set up remote reads from an MSMQ queue to a WCF service hosted on another machine. I seem to have all my application settings correct, but I'm being screwed over by machine-level configuration on the service machine: the service machine won't run in Active Directory mode, no matter what I do.

After searching for the problem, I found this page on John Breakwell's MSDN blog. It describes the problem: essentially there's a legacy msmq object left around when you install MSMQ Server and Active Directory Integration features together in the same transaction. Here's how you **actually** fix the problem:


  1. Uninstall all of the MSMQ features.
  2. Execute this PowerShell command (or one similar to it) to actually delete the Active Directory object described in the article (which doesn't go into nearly enough detail on this point):  get-adobject -filter “name -eq ‘msmq'” | Where { $_.DistinguishedName -eq ‘CN=msmq,CN=MyAffectedServerNameHere,OU=Web Servers,OU=Member Servers,DC=MyDomainNameHere,DC=Network,DC=ads’} | Remove-ADObject
  3. Reinstall **just** MSMQ server, then reboot your machine.
  4. Reinstall **just** MSMQ active directory integration, then reboot your machine.
You should now be good to go.

Solving "Binding validation failed because the binding's MsmqAuthenticationMode property is set to WindowsDomain but MSMQ is installed with Active Directory integration disabled"

I've been trying to set up remote reads from an MSMQ queue to a WCF service hosted on another machine. I seem to have all my application settings correct, but I'm being screwed over by machine-level configuration on the service machine: the service machine won't run in Active Directory mode, no matter what I do.

After searching for the problem, I found this page on John Breakwell's MSDN blog. It describes the problem: essentially there's a legacy msmq object left around when you install MSMQ Server and Active Directory Integration features together in the same transaction. Here's how you **actually** fix the problem:


  1. Uninstall all of the MSMQ features.
  2. Execute this PowerShell command (or one similar to it) to actually delete the Active Directory object described in the article (which doesn't go into nearly enough detail on this point):  get-adobject -filter “name -eq ‘msmq'” | Where { $_.DistinguishedName -eq ‘CN=msmq,CN=MyAffectedServerNameHere,OU=Web Servers,OU=Member Servers,DC=MyDomainNameHere,DC=Network,DC=ads’} | Remove-ADObject
  3. Reinstall **just** MSMQ server, then reboot your machine.
  4. Reinstall **just** MSMQ active directory integration, then reboot your machine.
You should now be good to go.

Thursday, September 01, 2016

Unblocking zip files, the permanent solution

My team recently migrated their code to Visual Studio Online (aka VSO aka VSTS), which means that any time we do our builds, we now have to download our build output through the browser as a zip file rather than copying from a file share as we formerly did when our code was built on-premise. As a consequence of this, we now stumble across a feature of Windows: automatic file blocking.

Any time we download a zip from the internet, any scripts extracted from it are automatically blocked by Windows using metadata attached to the file in the NTFS file system. This means we have to manually unblock our scripts every time we download a build and want to deploy it (But Alex, why aren't you deploying your systems automatically through a deployment manager ? Our company isn't there yet, but we're getting there). That said, there's a way to disable this feature, detailed here:

http://winaero.com/blog/disable-downloaded-files-from-being-blocked-in-windows-10/

The short of it is that there exists a group policy for disabling tracking of zone information for files downloaded from the Internet.

Start -> Run -> gpedit.msc -> Local Computer Policy -> User Configuration -> Administrative Templates -> Windows Components -> Attachment Manager -> "Do not preserve zone information in file attachments" : Enabled.

Done.