CRM 2011 – Acessar WCF (Multi Autenticações)


Pessoal,

Eu já havia feito posts sobre a autenticação no CRM 2011:

CRM 2011 – Autenticação Office 365

CRM 2011 – Acessar WCF [LiveId (Obsoleto)]

CRM 2011 – Acessar WCF (OnPremises)

Porém, com o surgimento da Online Federation Authentication (Office 365 Authentication), houveram algumas mudanças na autenticação do CRM 2011.

Assim este post unificará todas as autenticações utilizadas até o momento para o CRM 2011.

Neste post apenas fiz uma adaptação ao próprio material do SDK (Sample: Authenticate Users with Microsoft Dynamics CRM Web Services) que foi adicionado provavelmente no rollup 12. O post serve de alerta, caminho curto e já implementa uma classe que retorna a conexão criada e existe aproveitamento de sessão, caso ela já tenha sido criada.

Não se esqueçam de adicionar a classe (SDK/samplecode/cs/helpercode.deviceidmanager.cs) no projeto. Se ainda não baixou o SDK, use este link.

using System;
using System.Configuration;
using System.ServiceModel.Description;
using Microsoft.Crm.Sdk.Messages;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk.Discovery;

namespace TiagoCardoso.Comuns
{
    public class Connection
    {
        private OrganizationServiceProxy service { get; set; }

        #region Class Level Members
        // To get discovery service address and organization unique name,
        // Sign in to your CRM org and click Settings, Customization, Developer Resources.
        // On Developer Resource page, find the discovery service address under Service Endpoints and organization unique name under Your Organization Information.
        private String _discoveryServiceAddress = "http://SUA_ORGANIZACAO/XRMServices/2011/Discovery.svc" // OnPremises;
        //private String _discoveryServiceAddress = "https://disco.crm.dynamics.com/XRMServices/2011/Discovery.svc" // Online;
        private String _organizationUniqueName = "SUA_ORGANIZACAO";
        // Provide your user name and password.
        private String _userName = "USUARIO";
        private String _password = "SENHA";

        // Provide domain name for the On-Premises org.
        private String _domain = "DOMINIO"; // Informar somente se for uma conexão OnPremises
        #endregion Class Level Members

        #region How To Sample Code
        ///
        ///
        ///
        public OrganizationServiceProxy GetConnection()
        {
            if (service == null)
            {
                IServiceManagement serviceManagement =
                            ServiceConfigurationFactory.CreateManagement(
                            new Uri(_discoveryServiceAddress));
                AuthenticationProviderType endpointType = serviceManagement.AuthenticationType;

                // Set the credentials.
                AuthenticationCredentials authCredentials = GetCredentials(endpointType);

                String organizationUri = String.Empty;
                // Get the discovery service proxy.
                using (DiscoveryServiceProxy discoveryProxy =
                    GetProxy<IDiscoveryService, DiscoveryServiceProxy>(serviceManagement, authCredentials))
                {
                    // Obtain organization information from the Discovery service.
                    if (discoveryProxy != null)
                    {
                        // Obtain information about the organizations that the system user belongs to.
                        OrganizationDetailCollection orgs = DiscoverOrganizations(discoveryProxy);
                        // Obtains the Web address (Uri) of the target organization.
                        organizationUri = FindOrganization(_organizationUniqueName,
                            orgs.ToArray()).Endpoints[EndpointType.OrganizationService];
                    }
                }

                if (!String.IsNullOrWhiteSpace(organizationUri))
                {
                    IServiceManagement orgServiceManagement =
                        ServiceConfigurationFactory.CreateManagement(
                        new Uri(organizationUri));

                    // Set the credentials.
                    AuthenticationCredentials credentials = GetCredentials(endpointType);

                    // Get the organization service proxy.
                    using (OrganizationServiceProxy organizationProxy =
                        GetProxy<IOrganizationService, OrganizationServiceProxy>(orgServiceManagement, credentials))
                    {
                        // This statement is required to enable early-bound type support.
                        organizationProxy.EnableProxyTypes();

                        service = organizationProxy;
                    }
                }
            }

            return service;
        }

        ///
        /// Obtain the AuthenticationCredentials based on AuthenticationProviderType.
        ///
        ///An AuthenticationProviderType of the CRM environment.
        /// Get filled credentials.
        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;
        }

        ///
        /// Discovers the organizations that the calling user belongs to.
        ///
        ///A Discovery service proxy instance.
        /// Array containing detailed information on each organization that
        /// the user belongs to.
        public OrganizationDetailCollection DiscoverOrganizations(
            IDiscoveryService service)
        {
            if (service == null) throw new ArgumentNullException("service");
            RetrieveOrganizationsRequest orgRequest = new RetrieveOrganizationsRequest();
            RetrieveOrganizationsResponse orgResponse =
                (RetrieveOrganizationsResponse)service.Execute(orgRequest);

            return orgResponse.Details;
        }

        ///
        /// Finds a specific organization detail in the array of organization details
        /// returned from the Discovery service.
        ///
        ///The unique name of the organization to find.
        ///Array of organization detail object returned from the discovery service.
        /// Organization details or null if the organization was not found.
        ///
        public 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)
                {
                    orgDetail = detail;
                    break;
                }
            }
            return orgDetail;
        }

        ///
        /// Generic method to obtain discovery/organization service proxy instance.
        ///
        ///
        /// Set IDiscoveryService or IOrganizationService type to request respective service proxy instance.
        ///
        ///
        /// Set the return type to either DiscoveryServiceProxy or OrganizationServiceProxy type based on TService type.
        ///
        ///An instance of IServiceManagement
        ///The user's Microsoft Dynamics CRM logon credentials.
        ///
        private TProxy GetProxy<TService, TProxy>(
            IServiceManagement serviceManagement,
            AuthenticationCredentials authCredentials)
            where TService : class
            where TProxy : ServiceProxy
        {
            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), 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), typeof(ClientCredentials) })
                .Invoke(new object[] { serviceManagement, authCredentials.ClientCredentials });
        }

        #endregion How To Sample Code
    }
}

Como eu disse não tem nada além do SDK, mas fica o link…

[]’s,

Tiago Cardoso

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s

Este site utiliza o Akismet para reduzir spam. Saiba como seus dados em comentários são processados.