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