Inquiridor
SSIS para CRM 2011 com ADFS

Pergunta
-
Todas as Respostas
-
Isaias,
No final das contas precisa de uma classe autenticadora do CRM 2011 via ADFS, pode usar este exemplo para se comunicar:
http://tiagomcardoso.wordpress.com/2012/06/12/crm-2011-acessar-web-service/
Tiago Michelini Cardoso MVP - MCC - MCTS
https://tiagomcardoso.wordpress.com/ -
-
Ok Isaias,
Onde está o seu problema? Não está obtendo a autenticação? Não conseguiu implementar o código?
Att,
Tiago Michelini Cardoso MVP - MCC - MCTS
https://tiagomcardoso.wordpress.com/ -
Boa tarde, Tiago.
Obrigado pela resposta.
Bom, acho que seja na mecânica de autenticação do usuário.
Antes, estava usando o seguinte código para configurar e acessar o webservice do CRM, Organization.svc, no SSIS com o protocolo http:public static IOrganizationService GetCRMService(string ServerHost, string OrgName, string UserName, string Domain, string Pwd) { Uri organizationUri = new Uri(string.Format("{0}/{1}/XRMServices/2011/Organization.svc?wsdl", ServerHost, OrgName)); SymmetricSecurityBindingElement security = new SymmetricSecurityBindingElement(); security.ProtectionTokenParameters = new SspiSecurityTokenParameters(); HttpTransportBindingElement htbe = new HttpTransportBindingElement(); htbe.MaxReceivedMessageSize = 1000000000; CustomBinding binding = new CustomBinding(); binding.Elements.Add(security); TextMessageEncodingBindingElement tmebe = new TextMessageEncodingBindingElement(MessageVersion.Soap12WSAddressing10, Encoding.UTF8); binding.Elements.Add(tmebe); binding.Elements.Add(htbe); EndpointAddress address = new EndpointAddress(organizationUri, EndpointIdentity.CreateUpnIdentity(string.Format("{0}@{1}", UserName, Domain)), new AddressHeader[] { }); OrganizationServiceClient osclient = new OrganizationServiceClient(binding, address); osclient.ClientCredentials.Windows.ClientCredential = new System.Net.NetworkCredential(UserName, Pwd, Domain); return (IOrganizationService)osclient; }
Mas com a implantação do ADFS este código não dar suporte a integração do SSIS com o serviço do CRM 2011. E através de varias pesquisas fiz vários testes mas sem sucesso.
Tiago, gostaria de ajuda para fazer este código funcionar com ADFS (https). -
Isaias,
Veja um exemplo, nele tenho ao meu ver todos os tipos de autenticação Live ID, AD e Federation, aqui também usamos ADFS, e esta classe faz a conexão sem problemas:
using System; using System.ServiceModel; using System.ServiceModel.Description; using System.Reflection; using Microsoft.Xrm.Sdk; using Microsoft.Xrm.Sdk.Client; using Microsoft.Xrm.Sdk.Discovery; using System.Net; using System.Text; using System.Collections; using System.Configuration; namespace Autenticacao { public class Autenticacao { public Autenticacao(string organization) { _organizationUniqueName = organization; _discoveryServiceAddress = "https://URL_CRM/XRMServices/2011/Discovery.svc"; } // Variáveis auxiliares private String _organizationUniqueName; private String _discoveryServiceAddress; private String _userName = "USER"; private String _password = "PASSWORD"; private String _domain = "DOMAIN"; // OrganizationServiceProxy responsável pelo acesso ao WCF do CRM private OrganizationServiceProxy _organizationProxy = null; public OrganizationServiceProxy organizationProxy { get { if (_organizationProxy == null) _organizationProxy = GetProxy<IOrganizationService, OrganizationServiceProxy>(orgServiceManagement, credentials); return _organizationProxy; } } // private IServiceManagement<IOrganizationService> _orgServiceManagement = null; private IServiceManagement<IOrganizationService> orgServiceManagement { get { if (_orgServiceManagement == null) _orgServiceManagement = ServiceConfigurationFactory.CreateManagement<IOrganizationService>(new Uri(organizationUri)); return _orgServiceManagement; } } private AuthenticationCredentials _credentials = null; private AuthenticationCredentials credentials { get { if (_credentials == null) _credentials = GetCredentials(endpointType); return _credentials; } } private IServiceManagement<IDiscoveryService> _serviceManagement = null; private IServiceManagement<IDiscoveryService> serviceManagement { get { if (_serviceManagement == null) _serviceManagement = ServiceConfigurationFactory.CreateManagement<IDiscoveryService>(new Uri(_discoveryServiceAddress)); return _serviceManagement; } } private AuthenticationProviderType _endpointType = AuthenticationProviderType.Federation;//ActiveDirectory; private AuthenticationProviderType endpointType { get { if (_endpointType == AuthenticationProviderType.None) _endpointType = serviceManagement.AuthenticationType; return _endpointType; } } private AuthenticationCredentials _authCredentials = null; private AuthenticationCredentials authCredentials { get { if (_authCredentials == null) _authCredentials = GetCredentials(endpointType); return _authCredentials; } } private String _organizationUri = String.Empty; private string organizationUri { get { if (_organizationUri == String.Empty) { using (DiscoveryServiceProxy discoveryProxy = GetProxy<IDiscoveryService, DiscoveryServiceProxy>(serviceManagement, authCredentials)) { if (discoveryProxy != null) { OrganizationDetailCollection orgs = DiscoverOrganizations(discoveryProxy); _organizationUri = FindOrganization(_organizationUniqueName, orgs.ToArray()).Endpoints[EndpointType.OrganizationService]; } } } return _organizationUri; } } private ClientCredentials _credencial = null; private ClientCredentials Credencials { get { if (_credencial == null) { _credencial = new ClientCredentials(); _credencial.Windows.ClientCredential = new NetworkCredential(_userName, _password); } return _credencial; } } /// <summary> /// Obtain the AuthenticationCredentials based on AuthenticationProviderType. /// </summary> /// <param name="endpointType">An AuthenticationProviderType of the CRM environment.</param> /// <returns>Get filled credentials.</returns> private AuthenticationCredentials GetCredentials(AuthenticationProviderType endpointType) { AuthenticationCredentials authCredentials = new AuthenticationCredentials(); switch (endpointType) { case AuthenticationProviderType.ActiveDirectory: authCredentials.ClientCredentials.Windows.ClientCredential = new System.Net.NetworkCredential(_userName, _password, _domain); break; case AuthenticationProviderType.LiveId: authCredentials.ClientCredentials.UserName.UserName = _userName; authCredentials.ClientCredentials.UserName.Password = _password; authCredentials.SupportingCredentials = new AuthenticationCredentials(); authCredentials.SupportingCredentials.ClientCredentials = Microsoft.Crm.Services.Utility.DeviceIdManager.LoadOrRegisterDevice(); break; default: // For Federated and OnlineFederated environments. authCredentials.ClientCredentials.UserName.UserName = _userName; authCredentials.ClientCredentials.UserName.Password = _password; // For OnlineFederated single-sign on, you could just use current UserPrincipalName instead of passing user name and password. // authCredentials.UserPrincipalName = UserPrincipal.Current.UserPrincipalName; //Windows/Kerberos break; } return authCredentials; } /// <summary> /// Discovers the organizations that the calling user belongs to. /// </summary> /// <param name="service">A Discovery service proxy instance.</param> /// <returns>Array containing detailed information on each organization that /// the user belongs to.</returns> private OrganizationDetailCollection DiscoverOrganizations(IDiscoveryService service) { if (service == null) throw new ArgumentNullException("service"); RetrieveOrganizationsRequest orgRequest = new RetrieveOrganizationsRequest(); RetrieveOrganizationsResponse orgResponse = (RetrieveOrganizationsResponse)service.Execute(orgRequest); return orgResponse.Details; } /// <summary> /// Finds a specific organization detail in the array of organization details /// returned from the Discovery service. /// </summary> /// <param name="orgUniqueName">The unique name of the organization to find.</param> /// <param name="orgDetails">Array of organization detail object returned from the discovery service.</param> /// <returns>Organization details or null if the organization was not found.</returns> /// <seealso cref="DiscoveryOrganizations"/> private OrganizationDetail FindOrganization(string orgUniqueName, OrganizationDetail[] orgDetails) { if (String.IsNullOrWhiteSpace(orgUniqueName)) throw new ArgumentNullException("orgUniqueName"); if (orgDetails == null) throw new ArgumentNullException("orgDetails"); OrganizationDetail orgDetail = null; foreach (OrganizationDetail detail in orgDetails) { //if (String.Compare(detail.UniqueName, orgUniqueName, StringComparison.InvariantCultureIgnoreCase) == 0) if (String.Compare(detail.UrlName, orgUniqueName, StringComparison.InvariantCultureIgnoreCase) == 0) { orgDetail = detail; break; } } return orgDetail; } /// <summary> /// Generic method to obtain discovery/organization service proxy instance. /// </summary> /// <typeparam name="TService"> /// Set IDiscoveryService or IOrganizationService type to request respective service proxy instance. /// </typeparam> /// <typeparam name="TProxy"> /// Set the return type to either DiscoveryServiceProxy or OrganizationServiceProxy type based on TService type. /// </typeparam> /// <param name="serviceManagement">An instance of IServiceManagement</param> /// <param name="authCredentials">The user's Microsoft Dynamics CRM logon credentials.</param> /// <returns></returns> private TProxy GetProxy<TService, TProxy>(IServiceManagement<TService> serviceManagement, AuthenticationCredentials authCredentials) where TService : class where TProxy : ServiceProxy<TService> { Type classType = typeof(TProxy); if (serviceManagement.AuthenticationType != AuthenticationProviderType.ActiveDirectory) { AuthenticationCredentials tokenCredentials = serviceManagement.Authenticate(authCredentials); // Obtain discovery/organization service proxy for Federated, LiveId and OnlineFederated environments. // Instantiate a new class of type using the 2 parameter constructor of type IServiceManagement and SecurityTokenResponse. return (TProxy)classType .GetConstructor(new Type[] { typeof(IServiceManagement<TService>), typeof(SecurityTokenResponse) }) .Invoke(new object[] { serviceManagement, tokenCredentials.SecurityTokenResponse }); } // Obtain discovery/organization service proxy for ActiveDirectory environment. // Instantiate a new class of type using the 2 parameter constructor of type IServiceManagement and ClientCredentials. return (TProxy)classType .GetConstructor(new Type[] { typeof(IServiceManagement<TService>), typeof(ClientCredentials) }) .Invoke(new object[] { serviceManagement, authCredentials.ClientCredentials }); } } }
Note que existe uma parte hard code, como o login, senha e etc, troque isso pelo que achar mais conveniente.
Att,
Tiago Michelini Cardoso MVP - MCC - MCTS
https://tiagomcardoso.wordpress.com/- Editado Tiago Michelini CardosoMVP, Moderator quarta-feira, 17 de outubro de 2012 12:58
- Sugerido como Resposta Tiago Michelini CardosoMVP, Moderator quarta-feira, 17 de outubro de 2012 12:58
-
-
Se for complicado alterar, crie em um projeto separado, gere uma dll e depois importe no SSIS. Ou exponha através de um serviço...
Tiago Michelini Cardoso MVP - MCC - MCTS
https://tiagomcardoso.wordpress.com/ -
Boa tarde, Tiago.
Obrigado pela resposta.
O problema é que o SSIS 2008 trabalha com o FrameWork 3.5, e neste framework não há suporte para as bibliotecas do XRM:
using Microsoft.Xrm.Sdk; using Microsoft.Xrm.Sdk.Client; using Microsoft.Xrm.Sdk.Discovery;
Já fiz varios testes porém sem sucesso. Veja o erro:
Warning 1 Resolved file has a bad image, no metadata, or is otherwise inaccessible. Could not load file or assembly '..\CrmAuthenticate.dll' or one of its dependencies. This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded. st_1ac6f54779764fa58f9054ea6bd80e64
Esta dependencia é por causa das bibliotecas acima.
Nota: O código acima é funcional. O teste foi realizado através de app console, com o FrameWork 4.0, resultado foi bem sucedido.
Isaias Silva
- Editado Isaias José da Silva quinta-feira, 18 de outubro de 2012 18:57