Friday, 7 June 2013

CRM 2011 HTTPS Endpoint with SSIS and ADFS

After quite a bit of work, I finally managed to get a connection working with the CRM 2011 Https endpoint, using no config file, below is the code I used to achieve this.

private static IOrganizationService GetHttpsCRMService(string serverUrl, string adfsUrl, string username, string password)
        {
            Uri organizationUriIFD = new Uri(serverUrl + "/XRMServices/2011/Organization.svc");
                        
            EndpointAddress endpointAddress = new EndpointAddress(organizationUriIFD);

            CustomBinding customBinding = new CustomBinding();
            customBinding.Name = "CustomBinding";
            
            var tsBE = new TransportSecurityBindingElement();
            tsBE.AllowInsecureTransport = false;
            tsBE.IncludeTimestamp = true;


            EndpointAddress usernameMixed = new EndpointAddress(adfsUrl + "/adfs/services/trust/13/usernamemixed");
            WS2007HttpBinding wsbinding = new WS2007HttpBinding(SecurityMode.TransportWithMessageCredential);
            wsbinding.MaxReceivedMessageSize = 65536;
            wsbinding.MaxBufferPoolSize = 524288;
            wsbinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
            wsbinding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
            wsbinding.Security.Message.EstablishSecurityContext = false;

            IssuedSecurityTokenParameters stP = new IssuedSecurityTokenParameters(null, usernameMixed, wsbinding);
            stP.IssuerMetadataAddress = new EndpointAddress(new Uri(adfsUrl + "/adfs/services/trust/mex"));

            var additionalRquestParameters =
                @"<trust:SecondaryParameters xmlns:trust='http://docs.oasis-open.org/ws-sx/ws-trust/200512'>" +
                @"    <trust:KeyType xmlns:trust='http://docs.oasis-open.org/ws-sx/ws-trust/200512'>http://docs.oasis-open.org/ws-sx/ws-trust/200512/SymmetricKey</trust:KeyType>" +
                @"    <trust:KeySize xmlns:trust='http://docs.oasis-open.org/ws-sx/ws-trust/200512'>256</trust:KeySize>" +
                @"    <trust:Claims Dialect='http://schemas.xmlsoap.org/ws/2005/05/identity' xmlns:trust='http://docs.oasis-open.org/ws-sx/ws-trust/200512'>" +
                @"        <wsid:ClaimType Uri='http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn' xmlns:wsid='http://schemas.xmlsoap.org/ws/2005/05/identity' />" +
                @"    </trust:Claims>" +
                @"    <trust:KeyWrapAlgorithm xmlns:trust='http://docs.oasis-open.org/ws-sx/ws-trust/200512'>http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p</trust:KeyWrapAlgorithm>" +
                @"    <trust:EncryptWith xmlns:trust='http://docs.oasis-open.org/ws-sx/ws-trust/200512'>http://www.w3.org/2001/04/xmlenc#aes256-cbc</trust:EncryptWith>" +
                @"    <trust:SignWith xmlns:trust='http://docs.oasis-open.org/ws-sx/ws-trust/200512'>http://www.w3.org/2000/09/xmldsig#hmac-sha1</trust:SignWith>" +
                @"    <trust:CanonicalizationAlgorithm xmlns:trust='http://docs.oasis-open.org/ws-sx/ws-trust/200512'>http://www.w3.org/2001/10/xml-exc-c14n#</trust:CanonicalizationAlgorithm>" +
                @"    <trust:EncryptionAlgorithm xmlns:trust='http://docs.oasis-open.org/ws-sx/ws-trust/200512'>http://www.w3.org/2001/04/xmlenc#aes256-cbc</trust:EncryptionAlgorithm>" +
                @"</trust:SecondaryParameters>";

            System.Xml.XmlDocument additionalParamDoc = new System.Xml.XmlDocument();
            additionalParamDoc.LoadXml(additionalRquestParameters);

            stP.AdditionalRequestParameters.Add(additionalParamDoc.DocumentElement);
            stP.RequireDerivedKeys = false;
            stP.KeySize = 256;
            stP.KeyType = System.IdentityModel.Tokens.SecurityKeyType.SymmetricKey;
            
            tsBE.LocalClientSettings.DetectReplays = false;
            tsBE.LocalServiceSettings.DetectReplays = false;
            tsBE.EndpointSupportingTokenParameters.Endorsing.Add(stP);



            customBinding.Elements.Add(tsBE);

            var textEncoding = new System.ServiceModel.Channels.TextMessageEncodingBindingElement();
            var httpsTransport = new System.ServiceModel.Channels.HttpsTransportBindingElement();

            customBinding.Elements.Add(textEncoding);

            customBinding.Elements.Add(httpsTransport);
            customBinding.ReceiveTimeout = new TimeSpan(0, 10, 0);
            customBinding.SendTimeout = new TimeSpan(0, 1, 0);
            customBinding.OpenTimeout = new TimeSpan(0, 1, 0);
            customBinding.CloseTimeout = new TimeSpan(0, 1, 0);

            var contract = new System.ServiceModel.Description.ContractDescription("IOraganizationService", "http://schemas.microsoft.com/xrm/2011/Contracts/Services");
            contract.ContractType = typeof(IOrganizationService);

            OrganizationServiceClient osClient = new OrganizationServiceClient(customBinding, endpointAddress);
            osClient.ClientCredentials.UserName.UserName = username;
            osClient.ClientCredentials.UserName.Password = password;
            
            return (IOrganizationService)osClient;
        }