Sample: Authenticate Users with Microsoft Dynamics CRM Web Services
[Applies to: Microsoft Dynamics CRM 2011 and Microsoft Dynamics CRM Online]
This sample shows how to authenticate a user with any Microsoft Dynamics CRM deployment and obtain a reference to the web services. This sample includes support for Microsoft Office 365 users provisioned in Microsoft Dynamics CRM Online.
Demonstrates
This sample demonstrates how to authenticate a user with any Microsoft Dynamics CRM 2011 and Microsoft Dynamics CRM Online deployment and make web service calls. This sample does not rely on the CrmServiceHelpers.cs helper code. For a sample that does use helper code, see Sample: Quick Start for Microsoft Dynamics CRM.
Example
using System; using System.ServiceModel; using System.ServiceModel.Description; using System.Reflection; // These namespaces are found in the Microsoft.Xrm.Sdk.dll assembly // located in the SDK\bin folder of the SDK download. using Microsoft.Xrm.Sdk; using Microsoft.Xrm.Sdk.Query; using Microsoft.Xrm.Sdk.Client; using Microsoft.Xrm.Sdk.Discovery; using Microsoft.Crm.Sdk.Messages; namespace Microsoft.Crm.Sdk.Samples { /// <summary> /// Demonstrate how to do basic authentication using IServiceManagement and SecurityTokenResponse. /// </summary> class AuthenticateWithNoHelp { #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 = "https://dev.crm.dynamics.com/XRMServices/2011/Discovery.svc"; private String _organizationUniqueName = "OrganizationUniqueName"; // Provide your user name and password. private String _userName = "username@mydomain.com"; private String _password = "password"; // Provide domain name for the On-Premises org. private String _domain = "mydomain"; #endregion Class Level Members #region How To Sample Code /// <summary> /// /// </summary> public void Run() { IServiceManagement<IDiscoveryService> serviceManagement = ServiceConfigurationFactory.CreateManagement<IDiscoveryService>( 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<IOrganizationService> orgServiceManagement = ServiceConfigurationFactory.CreateManagement<IOrganizationService>( 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(); // Now make an SDK call with the organization service proxy. // Display information about the logged on user. Guid userid = ((WhoAmIResponse)organizationProxy.Execute( new WhoAmIRequest())).UserId; SystemUser systemUser = organizationProxy.Retrieve("systemuser", userid, new ColumnSet(new string[] { "firstname", "lastname" })).ToEntity<SystemUser>(); Console.WriteLine("Logged on user is {0} {1}.", systemUser.FirstName, systemUser.LastName); } } } /// <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> 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; } /// <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"/> 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; } /// <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 }); } #endregion How To Sample Code #region Main method /// <summary> /// Standard Main() method used by most SDK samples. /// </summary> /// <param name="args"></param> static public void Main(string[] args) { try { AuthenticateWithNoHelp app = new AuthenticateWithNoHelp(); app.Run(); } catch (FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault> ex) { Console.WriteLine("The application terminated with an error."); Console.WriteLine("Timestamp: {0}", ex.Detail.Timestamp); Console.WriteLine("Code: {0}", ex.Detail.ErrorCode); Console.WriteLine("Message: {0}", ex.Detail.Message); Console.WriteLine("Trace: {0}", ex.Detail.TraceText); Console.WriteLine("Inner Fault: {0}", null == ex.Detail.InnerFault ? "No Inner Fault" : "Has Inner Fault"); } catch (System.TimeoutException ex) { Console.WriteLine("The application terminated with an error."); Console.WriteLine("Message: {0}", ex.Message); Console.WriteLine("Stack Trace: {0}", ex.StackTrace); Console.WriteLine("Inner Fault: {0}", null == ex.InnerException.Message ? "No Inner Fault" : ex.InnerException.Message); } catch (System.Exception ex) { Console.WriteLine("The application terminated with an error."); Console.WriteLine(ex.Message); // Display the details of the inner exception. if (ex.InnerException != null) { Console.WriteLine(ex.InnerException.Message); FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault> fe = ex.InnerException as FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault>; if (fe != null) { Console.WriteLine("Timestamp: {0}", fe.Detail.Timestamp); Console.WriteLine("Code: {0}", fe.Detail.ErrorCode); Console.WriteLine("Message: {0}", fe.Detail.Message); Console.WriteLine("Trace: {0}", fe.Detail.TraceText); Console.WriteLine("Inner Fault: {0}", null == fe.Detail.InnerFault ? "No Inner Fault" : "Has Inner Fault"); } } } // Additional exceptions to catch: SecurityTokenValidationException, ExpiredSecurityTokenException, // SecurityAccessDeniedException, MessageSecurityException, and SecurityNegotiationException. finally { Console.WriteLine("Press <Enter> to exit."); Console.ReadLine(); } } #endregion Main method } }
See Also
Microsoft Dynamics CRM 2011 and Microsoft Dynamics CRM Online
Send comments about this topic to Microsoft.
© 2012 Microsoft Corporation. All rights reserved.