I have an issue with the Windows Azure ACS and I can't quite determine if it's supposed to be that way, or if there's an error in my code.
I have a number of relying parties configured in the ACS and all of them are configured with HTTPS. Every service is configured in such a way that Token Encryption is required. For this, I've uploaded a certificate created using MakeCert.exe.
When the client communicates with the relying party, I add the public part of the certificate as the service certificate and I add the subject name as a DnsIdentity:
var identity = EndpointIdentity.CreateDnsIdentity( GetClientCertificateSubjectName() );
var serviceEndpointAddress = new EndpointAddress( new Uri( _serviceAddress ), identity );
// Creation of channel factory
if( channelFactory.Credentials != null ) {
channelFactory.Credentials.ServiceCertificate.DefaultCertificate = GetClientCertificate();
channelFactory.Credentials.ClientCertificate.Certificate = GetServiceIdentityCertificate();
}
Here's the thing: when I call the relying party over HTTPS, then I can skip the creation of the EndpointIdentity
and then the relying party will give me a correct answer. I can also skip setting the ServiceCertificate.DefaultCertificate
property or set a totally random certificate, and the relying party will still give me a correct answer.
When calling over HTTP, doing any of the above will result in the ACS erroring out with messages indicating that I haven't used the correct certificates. In short: when calling over HTTP, I can only communicate with the correct client certificate. I expected that this was the case for HTTPS as well.
I can imagine that the ChannelFactory<T>
or the ACS is smart enough to detect that HTTPS is used and that the configured encryption is skipped, in favour of SSL encryption. Sadly, I can't find any documentation that supports this idea.
My question is: Is it normal to ignore the EndpointIdentity
and certificates when calling a relying party over HTTPS? Or do I need additional configuration to make this work?
Thanks in advance!
The amount of information I gave turned out to be insufficient to properly answer the question. It turned out that it was all in the bindings we were creating. It creates a binding with the following piece of code:
public static Binding CreateServiceBinding( string acsCertificateEndpoint, string bindingNameSpace, bool useSsl ) {
var binding = new IssuedTokenWSTrustBinding( CreateAcsCertificateBinding(), new EndpointAddress( acsCertificateEndpoint ) );
if( useSsl ) {
binding.SecurityMode = SecurityMode.TransportWithMessageCredential;
}
if( !string.IsNullOrWhiteSpace( bindingNameSpace ) ) {
binding.Namespace = bindingNameSpace;
}
return binding;
}
public static CertificateWSTrustBinding CreateAcsCertificateBinding() {
return new CertificateWSTrustBinding( SecurityMode.TransportWithMessageCredential );
}
That results in the following:
For more information on the security modes, check out the following links:
https://msdn.microsoft.com/en-us/library/ms733098%28v=vs.110%29.aspx https://msdn.microsoft.com/en-us/library/ms731074%28v=vs.110%29.aspx
Hope this helps someone!