50

I'm trying to implement a pure WCF scenario where I want to call Dynamics CRM WCF service without relying on the SDK helper classes. Basically, I would like to implement federated authentication against Dynamics CRM 2011 using only native WCF support from the .net framework.

The reason I'm doing this is that I would like to port this scenario later-on to BizTalk.

I've successfully generated proxy classes with SvcUtil, but the part of the policies and security assertions are not compatible with the configuration schema. SvcUtil suggests to build the binding from code instead, which is what I'm trying to do.

The resulting code is here:

        private static void CallWcf()
    {
        OrganizationServiceClient client = null;

        try
        {
            // Login Live.com Issuer Binding

            var wsHttpBinding = new WSHttpBinding();
            wsHttpBinding.Security = new WSHttpSecurity();
            wsHttpBinding.Security.Mode = SecurityMode.Transport;

            // Endpoint Binding Elements

            var securityElement = new TransportSecurityBindingElement();
            securityElement.DefaultAlgorithmSuite = SecurityAlgorithmSuite.TripleDes;
            securityElement.IncludeTimestamp = true;
            securityElement.KeyEntropyMode = SecurityKeyEntropyMode.CombinedEntropy;
            securityElement.MessageSecurityVersion = MessageSecurityVersion.WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10;
            securityElement.SecurityHeaderLayout = SecurityHeaderLayout.Strict;

            var securityTokenParameters = new IssuedSecurityTokenParameters();
            securityTokenParameters.InclusionMode = SecurityTokenInclusionMode.AlwaysToRecipient;
            securityTokenParameters.ReferenceStyle = SecurityTokenReferenceStyle.Internal;
            securityTokenParameters.RequireDerivedKeys = false;
            securityTokenParameters.TokenType = null;
            securityTokenParameters.KeyType = SecurityKeyType.SymmetricKey;
            securityTokenParameters.KeySize = 192;
            securityTokenParameters.IssuerAddress = new EndpointAddress("https://login.live.com/extSTS.srf");
            securityTokenParameters.IssuerMetadataAddress = null;
            securityTokenParameters.DefaultMessageSecurityVersion = null;
            securityTokenParameters.IssuerBinding = wsHttpBinding;

            securityElement.EndpointSupportingTokenParameters.Signed.Add(securityTokenParameters);

            var textMessageEncodingElement = new TextMessageEncodingBindingElement();
            textMessageEncodingElement.MaxReadPoolSize = 64;
            textMessageEncodingElement.MaxWritePoolSize = 16;
            textMessageEncodingElement.MessageVersion = MessageVersion.Default;
            textMessageEncodingElement.WriteEncoding = System.Text.Encoding.UTF8;

            textMessageEncodingElement.ReaderQuotas.MaxStringContentLength = 8192;
            textMessageEncodingElement.ReaderQuotas.MaxArrayLength = 16384;
            textMessageEncodingElement.ReaderQuotas.MaxBytesPerRead = 4096;
            textMessageEncodingElement.ReaderQuotas.MaxNameTableCharCount = 16384;

            var httpsTransportElement = new HttpsTransportBindingElement();
            httpsTransportElement.ManualAddressing = false;
            httpsTransportElement.AuthenticationScheme = System.Net.AuthenticationSchemes.Anonymous;

            CustomBinding binding = new CustomBinding();
            binding.Elements.Add(securityElement);
            binding.Elements.Add(textMessageEncodingElement);
            binding.Elements.Add(httpsTransportElement);

            client = new OrganizationServiceClient(binding, new EndpointAddress(EndpointUri));
            client.ClientCredentials.UserName.UserName = Username;
            client.ClientCredentials.UserName.Password = Password;
            client.Open();

            var columnSet = new schemas.microsoft.com.xrm._2011.Contracts.ColumnSet();
            var identifier = new Guid("fbf8240e-2c85-e011-ad55-1cc1de0878eb");

            columnSet.Columns = new string[] { "name" };
            var entity = client.Retrieve("account", identifier, columnSet);
        }

        finally
        {
            if (client != null)
                client.Close();
        }
    }

I'm new to federated authentication and am having a hard time figuring out the potential differences between the many available bindings, so I would be grateful for any help in this regard.

John M. Wright
  • 4,477
  • 1
  • 43
  • 61
Maxime Labelle
  • 3,609
  • 2
  • 27
  • 48
  • 1
    Have you ever found out how to do this? – Jonas Sourlier Jan 27 '12 at 17:30
  • And, what SDK helper classes do you mean? – Jonas Sourlier Jan 27 '12 at 17:30
  • 1
    I did not pursue this and never found out. What I call SDK Helper Classes are the various samples that ship with the CRM 2011 SDK. – Maxime Labelle Feb 06 '12 at 21:22
  • @MaximeLabelle Are you still interested on how to do that or did the issue go away? – Konrad Viltersten Jan 23 '13 at 16:22
  • I'm still very much interested... – Maxime Labelle Jan 23 '13 at 17:45
  • I've played around with it for a few days but as far my laziness... hrmp... skills set the limit, you'll need to rely on the helper classes. They are free and open source so you can use them as you please. However, I understand that you perhaps wish to do that just to see if it's doable. Of course, there's always the option of downloading the WSDL file broadcast by the discovery service. Then you need no SDK. What's the task at hand here, if I may ask? – Konrad Viltersten Jan 25 '13 at 08:00
  • It's amazing that a question is open for so long with 42 votes. I have to find an answer to this. – Sid Jan 28 '14 at 07:15

1 Answers1

2

It is probably possible, but hugely complicated. We had a project using Dynamics which moved to ADFS, and required adding lots of extra code around refreshing tokens (code form autorefreshsecuritytoken.cs, deviceidmanager.cs and toolserviceproxies.cs from the SDK) and that was still using the SDK for everything.

Bare in mind you also need windows.identification installed in the OS which is another load of functionality to copy.

In the end you can always just use JustDecompile or similar to see what the SDK is doing.

Dave Glassborow
  • 3,253
  • 1
  • 30
  • 25