This documentation is archived and is not being maintained.

Walkthrough: Client to Server Authentication with CRM Online

Forefront
banner art

[Applies to: Microsoft Dynamics CRM 4.0]

Find the latest SDK documentation: CRM 2015 SDK

This walkthrough shows how to use Windows Live authentication to access Microsoft Dynamics CRM Online.

During this walkthrough you will learn how to do the following:

  • Use Visual Studio 2005 to create a console application that uses the Microsoft Dynamics CRM Online Web services.
  • Use Windows Live authentication for interacting with the Microsoft Dynamics CRM Online Web services.

This walkthrough uses C# sample code only. However, a Visual Basic .NET version of the code can be found at SDK\Walkthroughs\Authentication\VB\Passport.

Prerequisites

In order to complete this walkthrough, you will need the following:

Creating a Visual Studio 2005 Solution

Use Visual Studio to create a solution to build your code.

To create a Visual Studio 2005 solution

  1. In Microsoft Visual Studio 2005, on the File menu, point to New, and then click Project to open the New Project dialog box.
  2. In the Project types pane, select Visual C#.
  3. In the Templates pane, click Console Application.
  4. Type a name for your project and then click OK.

Downloading the Web Service Description Files

For programming against Microsoft Dynamics CRM Online, you have to obtain local copies of the Web Service Description Language (WSDL) files for your organization. Be aware that for the WSDL to be complete, you must repeat the following procedure if you make any customizations to entities in your organization.

  1. Open a Web browser and enter the URL for the Microsoft Dynamics CRM Online portal. For example:
    http://crm.dynamics.com
    
  2. Click the Log In Here button, enter your Windows Live account logon information, and then click Sign in.
  3. In the Navigation pane click Settings.
  4. In the Settings pane click Customization.
  5. In the Customization area, click Download Web Service Description Files.
  6. Click the CrmService.asmx icon.
  7. When the Web browser displays the WSDL, save the XML to a file on your hard disk. The procedure for saving the file will be different depending on the Web browser that you are using. In Internet Explorer 7, click the Page menu, and then click Save.
  8. Click the CrmDiscoveryService.asmx icon.
  9. Download the WSDL as you did before in step 7. If you see a CrmDiscoveryService Web page instead of WSDL, click the Service Description link to obtain the WSDL.
  10. Close the Web browser window that contains the WSDL definitions and sign out of Microsoft Dynamics CRM Online.

Adding Web References

You must add references to the required Microsoft Dynamics CRM Online Web services; in this case, you will add a reference to the CrmDiscoveryService Web service and the CrmService Web service.

To add the CrmDiscoveryService Web service reference

  1. In the Solution Explorer window, right-click your project name and select Add Web Reference.

    In the Add Web Reference wizard, type the URL for the CrmDiscoveryService WSDL XML file that you previously downloaded into the URL box, and then click Go. For example: file://C:\CrmDiscoveryService.xml.

  2. When the CrmDiscoveryService Web service is found, change the text in the Web reference name box to CrmSdk.Discovery and then click Add Reference.

To add the CrmService Web service reference

  1. In the Solution Explorer window, right-click your project name and select Add Web Reference.
  2. In the Add Web Reference wizard, type the URL for the CrmService WSDL XML file that you previously downloaded into the URL box, and then click Go. For example: file://C:\CrmServiceWsdl.xml
  3. When the CrmService Web service is found, change the text in the Web reference name box to CrmSdk and then click Add Reference.

Adding References

You must add references to the IdCrl Wrapper code that is used to simplify Windows Live authentication.

To copy the IdCrl assembiles to your program location

  1. Open the folder SDK\Bin.
  2. Copy the files idcrlwrapper.dll and msidcrl40.dll to the program location for your solution. For example:
    C:\Documents and Settings\user\My Documents\Visual Studio 2005\Projects\PassportAuth\PassportAuth\bin\Debug
    

To add the IdCrl assembiles

  1. In the Solution Explorer window, right-click your project name and select Add Reference.
  2. In the Add Reference dialog box, click the Browse tab.
  3. Browse to the folder SDK\Bin.
  4. Select IdCrlWrapper.dll and then click OK.

Accessing Microsoft Dynamics CRM Web Services

First you must access the Web service namespace and then create the CrmDiscoveryService Web service proxy. To do this, you will first add a using (or import) statement, which provides access to the namespace. Then, you can add code that instantiates the CrmDiscoveryService Web service. You also have to add the System.Web.Services.Protocols namespaces for error handling.

To add a using statement and class definition

Add the following lines to the top of your code file:

[C#]
using System;
using System.Xml;
using System.Text;
using System.Web.Services.Protocols;

// Microsoft Passport namespaces
using Microsoft.Crm.Passport.Sample;

namespace Microsoft.Crm.Sdk.Walkthrough
{
    // Import the Microsoft Dynamics CRM namespaces.
    using CrmSdk;
    using CrmSdk.Discovery;

    public class TimeoutSample
    {

    }

To add configuration information to your solution

Add the following code within the class definition and before the Main method. This code sets up the necessary variables such as the organization name. Make sure that you fill in the correct username, password, and organization values for your installation.

Notice that the following example code contains sample data for a user logon name and password. This is for illustration purposes only. User credentials should never be hard coded. For more information, see Building Secure ASP.NET Applications at msdn.microsoft.com/en-us/library/aa302415.aspx.

[C#]
        // Login information for authentication through the Windows Live service.
        static private string _username = "someone@microsoft.com";
        static private string _password = "password";
        static private string _partner = "crm.dynamics.com";
        static private string _environment = "Production";

        // Set the name and TCP port of the server hosting Microsoft Dynamics CRM Live.
        static private string _hostname = "dev.crm.dynamics.com";

        // Set the friendly name of the target organization.
        static private string _orgFriendlyName = "AdventureWorksCycle";

        // Define an expired authentication ticket error code.
        static private string EXPIRED_AUTH_TICKET = "8004A101";

        // Passport ticket required to recover from a CrmTicket time out.
        static private string _passportTicket;

        // Attempt a service call a maximum number of times before failing.
        static private int MAX_RETRIES = 5;

To add error handling to your solution

Add the following Main method. This code will provide some console output you can use to verify that your program is working.

[C#]
        [STAThread]
        public static void Main(string[] args)
        {
            try
            {
                TimeoutSample.Run();
                Console.WriteLine("Authentication was successfull.");
            }
            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);

                    SoapException se = ex.InnerException as SoapException;
                    if (se != null)
                        Console.WriteLine(se.Detail.InnerText);
                }
            }
            finally
            {
                Console.WriteLine("Press <Enter> to exit.");
                Console.ReadLine();
            }
        }

Your program will not build because the Run method does not exist. You will create this next.

To add the Run and InvokeServiceMethod methods

The InvokeServiceMethod contains all the code needed to use the discovery service to obtain the correct URL for the CrmService of your organization. A WhoAmI request is sent to the Web service to verify that the user has been authenticated successfully.

Add the following class methods after the Main method.

[C#]

        public static bool Run()

        {

            // Connect to Microsoft Dynamics CRM and invoke a Web service method.

            int firstAttempt = 1;

            InvokeServiceMethod(firstAttempt);

            return true;

        }

        public static void InvokeServiceMethod(int retryCount)

        {

            try

            {

                if (retryCount == MAX_RETRIES)

                {

                    // Throw an exception when the maximum retry count is reached. 

                    throw new Exception("An error occurred while attempting to authenticate.");

                }

                else

                {

                    // STEP 1,2: Retrieve a policy from the Discovery Web service.

                    CrmDiscoveryService discoveryService = new CrmDiscoveryService();

                    discoveryService.Url = String.Format(

                        "https://{0}/MSCRMServices/2007/{1}/CrmDiscoveryService.asmx",

                        _hostname, "Passport");

                    RetrievePolicyRequest policyRequest = new RetrievePolicyRequest();

                    RetrievePolicyResponse policyResponse =

                        (RetrievePolicyResponse)discoveryService.Execute(policyRequest);

                    // STEP 3,4: Retrieve a Passport ticket from the Windows Live service.

                    LogonManager lm = new LogonManager();

                    _passportTicket = lm.Logon(_username, _password, _partner, policyResponse.Policy,

                                               _environment);

                    // Dispose of the LogonManager object to avoid a FileNotOpen exception.

                    lm.Dispose();

                    // STEP 5,6: Retrieve organization information and a (Crm) ticket from the

                    // Discovery Web service. Retrieve a list of organizations that the logged on user

                    // is a member of.

                    RetrieveOrganizationsRequest orgRequest = new RetrieveOrganizationsRequest();

                    orgRequest.PassportTicket = _passportTicket;

                    RetrieveOrganizationsResponse orgResponse =

                        (RetrieveOrganizationsResponse)discoveryService.Execute(orgRequest);

                    // Locate the target organization name using the organization friendly name.

                    String orgUniqueName = String.Empty;

                    OrganizationDetail orgInfo = null;

                    foreach (OrganizationDetail orgDetail in orgResponse.OrganizationDetails)

                    {

                        if (orgDetail.FriendlyName.Equals(_orgFriendlyName))

                        {

                            orgInfo = orgDetail;

                            orgUniqueName = orgInfo.OrganizationName;

                            break;

                        }

                    }

                    // Retrieve the CrmTicket.

                    RetrieveCrmTicketRequest crmTicketRequest = new RetrieveCrmTicketRequest();

                    crmTicketRequest.OrganizationName = orgUniqueName;

                    crmTicketRequest.PassportTicket = _passportTicket;

                    RetrieveCrmTicketResponse crmTicketResponse =

                        (RetrieveCrmTicketResponse)discoveryService.Execute(crmTicketRequest);

                    // STEP 7: Create and configure an instance of the CrmService Web service.

                    CrmAuthenticationToken token = new CrmAuthenticationToken();

                    token.AuthenticationType = 1;

                    token.CrmTicket = crmTicketResponse.CrmTicket;

                    token.OrganizationName = crmTicketResponse.OrganizationDetail.OrganizationName;

                    CrmService crmService = new CrmService();

                    crmService.Url = crmTicketResponse.OrganizationDetail.CrmServiceUrl;

                    crmService.CrmAuthenticationTokenValue = token;

                    // Invoke the desired CrmService Web service methods.

                    WhoAmIRequest whoRequest = new WhoAmIRequest();

                    WhoAmIResponse whoResponse = (WhoAmIResponse)crmService.Execute(whoRequest);

                    systemuser user = (systemuser)crmService.Retrieve(EntityName.systemuser.ToString(),

                        whoResponse.UserId, new AllColumns());

                    Console.WriteLine("Login user's name is {0}", user.fullname);

                }

            }

            catch (SoapException ex)

            {

                // Handle the exception thrown from an expired ticket condition.

                if (GetErrorCode(ex.Detail) == EXPIRED_AUTH_TICKET)

                {

                    // Retry the CrmService web service call.

                    InvokeServiceMethod(retryCount++);

                }

                // If this was some other SOAP exception, rethrow the exception.

                throw ex;

            }

            catch (Exception ex)

            {

                // Handle the MAX_RETRY exception here.

                // Sample will just rethrow.

                throw ex;

            }

        }

To add the GetErrorCode method

Add the following class method after the InvokeServiceMethod method. This code extracts the error code from a SoapException.

[C#]
private static string GetErrorCode(XmlNode errorInfo)
{
   XmlNode code = errorInfo.SelectSingleNode("//code");

   if (code != null)
      return code.InnerText;
   else
      return "";
}

Now build and run your solution by pressing F5. If you get any compile errors, you can find the complete code sample in the SDK\Walkthroughs\Authentication\CS|VB\Passport folder.


© 2010 Microsoft Corporation. All rights reserved.


Show: