CRM 4.0: IFD - Authentication from a custom aspx page

Con risposta CRM 4.0: IFD - Authentication from a custom aspx page

  • Wednesday, May 12, 2010 12:58 PM
     
     

    I did read following post: http://social.microsoft.com/Forums/en-US/crmdevelopment/thread/81f8ba82-981d-40dd-893d-3add67436478

    I know that I need to create a ticket to be able to use IFD. My question is, how do I get UserId and Password from the user who have logged in to CRM from default IFD login page?

    ...

     

         ticketRequest.OrganizationName = orgName;
         ticketRequest.UserId = "domain\user_something.com";
         ticketRequest.Password = "password";
    

     

    ...

    Do I really need to create a custom login page for my customizations (and store credentials in asp.net cache), or is it possible to get user's credentials from Page.Context or CrmDiscoveryService?

     

All Replies

  • Wednesday, May 12, 2010 2:01 PM
     
     

    When using the CrmImpersonator there is no need to request a ticket. Requesting tickets is only need if you are connecting to the CRM webservice using IFD from outside the CRM web application the method CrmAuthenticationToken.ExtractCrmAuthenticationToken(Context, orgname) can be using to get a tocken which allready contains the ticket.

    The code below works in any aspx page for both IFD and AD authentication mode.

    using (new CrmImpersonator())
    {
        CrmAuthenticationToken token;
        if (offline == true)
        {
            token = new CrmAuthenticationToken();
        }
        else
        {
            token = CrmAuthenticationToken.ExtractCrmAuthenticationToken(Context, orgname);
        }
        token.OrganizationName = orgname;
        token.AuthenticationType = 0;

        //Create the Service
        CrmService service = new CrmService();
        service.Credentials = System.Net.CredentialCache.DefaultCredentials;
        service.CrmAuthenticationTokenValue = token;
        service.Url = crmurl;

        account account = new account();
        account.name = "Offline Impersonator: " + DateTime.Now.TimeOfDay.ToString();
        if (offline == false)
            account.ownerid = new Owner("systemuser", token.CallerId);

        service.Create(account);
    }

  • Thursday, May 13, 2010 9:10 AM
     
     

    We are using forms-based authentication in hosted deployment, so we need to create a CrmTicket.

    In "Microsoft CRM 4 - Security Model Architecture" on page 15:

    4. Forms sign-in page invokes the CRM Forms Authentication provider in the
    authentication pipeline, which attempts to validate the user.

    5. If the credentials are valid, the forms authentication provider generates a token,
    serializes it to a cookie and attaches it to the current HTTP header and redirects the
    browser to CRM application. The cookie and the underlying token is proof that the
    Forms Authentication provider has verified the user’s identity, and the hosted CRM
    Server can decrypt the token to obtain the user's unique identifier.

    In (5) "...and the hosted CRM Server can decrypt the token to obtain the user's unique identifier.", how to I do that? To create a service, I need to create a token. To create a token, I need to create a ticket with a UserID and Password. How do I get logged in user's UserID and Password?

  • Thursday, May 13, 2010 3:09 PM
     
     

    Hi , try to do   token = CrmAuthenticationToken.ExtractCrmAuthenticationToken(Context, orgname);

    thanks


    VenkataP
  • Friday, May 14, 2010 6:12 AM
     
     

    I did try Patrick's example and it failed with "HTTP status 401: Unauthorized - User was not found".

    We have a Multi-tenant hosted environment which is used with forms authentication. This is not a basic on-premise installation with IFD enabled. Our customizations is in ISV folder.

    Do you mean that "token = CrmAuthenticationToken.ExtractCrmAuthenticationToken(Context, orgname);" should work with our environment and customizations?

  • Tuesday, May 18, 2010 12:51 PM
     
     

    Hi Sanxioon,

    we also have same enviornment with onpremise +IFD & also we struggle lot to remove double authentication problem. At last we achieved using

    same line code

    token = CrmAuthenticationToken.ExtractCrmAuthenticationToken(this.Context, orgname);

    we use the WhoAmIRequest  class to get the information of logged user & there is no need to create your own login for custom pages(if the pages are displayed with in CRM )

    Thanks

     

     


    VenkataP
  • Tuesday, May 25, 2010 11:08 AM
     
     

    Hi All,

    The context does not work for the IFD configuration in my case as we have cleared the httpmodules from the web.config file .

    Is there any other way I can make it work.

     

    Regards

     


    Susan
  • Tuesday, May 25, 2010 11:17 AM
     
     
    The authentication token is stored in a cookie and the ExtractCrmAuthenticationToken just reads this and converts it to a CrmAuthenticationToken object. This cookie contains the Ticket needed for IFD authentication, using .NET reflector you can see what the ExtractCrmAuthenticationToken method is doing and copy this into your own application.
  • Tuesday, May 25, 2010 7:01 PM
     
     

    Thanks Patrick..

    Still I get the error "UserId not found for the current user on the context".

    The code I have been using to create CRM service is as below:

     

    using (new CrmImpersonator())

    {

    CrmAuthenticationToken token;

    string orgname = "Test";

    string crmurl = ConfigurationManager.AppSettings["CrmServiceUrl"].ToString();

    token = CrmAuthenticationToken.ExtractCrmAuthenticationToken(Context, orgname);

     

    token.OrganizationName = orgname;

    token.AuthenticationType = 0;

    //Create the Service

    CrmService service = new CrmService();

    service.Credentials = System.Net.CredentialCache.DefaultCredentials;

    service.CrmAuthenticationTokenValue = token;

    service.Url = crmurl;

    account account = new account();

    account.name = "Account : " + DateTime.Now.TimeOfDay.ToString();

     

    account.ownerid = new Owner("systemuser", token.CallerId);

    service.Create(account);

    }

     

    Thanks

     


    Susan
  • Tuesday, May 25, 2010 8:35 PM
    Moderator
     
     
    You do need to keep the CRM HttpModules (MapOrg and CrmAuthentication) to get IFD authentication to work. I think that you also should not create an IIS application for your virtual directory, which means you'll need to put your assemblies in the GAC or the <webroot>\bin folder (not creating an IIS application avoids the need to add the Microsoft.Crm.WebServices.dll to the GAC, which is the normal alternative to removing the HttpModules)
    Microsoft CRM MVP - http://mscrmuk.blogspot.com  http://www.excitation.co.uk
  • Wednesday, May 26, 2010 3:49 PM
     
     

    Hi David,

    What you are saying sounds logical to me in theory, if we are able to make the CRM .Net extension part of the running existing MSCRM website hosted solution, then the problem of context will not arise.

    I did what you suggested and now I get the following exception.

    Description: An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately.

    Parser Error Message: It is an error to use a section registered as allowDefinition='MachineToApplication' beyond application level.  This error can be caused by a virtual directory not being configured as an application in IIS.

    Source Error:

     

     

    Please let me know how I can overcome this problem.

     

    thanks in advance

    Server Error in '/' Application.

    Configuration Error

     


    Susan
  • Wednesday, May 26, 2010 9:14 PM
    Moderator
     
     Answered

    Susan

    The error message doesn't go into sufficient detail to be certain as to the solution, but the most likely cause would be an <authentication> element in your web.config file. This can be removed, which is likely to solve the problem. You should be able to make your application work without a web.config file in your virtual directory, though if you know you need specific settings then they should be added.

    If you still have problems I suggest you post your web.config file here to give us more information

    David


    Microsoft CRM MVP - http://mscrmuk.blogspot.com  http://www.excitation.co.uk
  • Tuesday, January 18, 2011 4:18 AM
     
      Has Code

    Can anyone help me with this?  I'm having the same problem -- I'm continually getting UserId not found for the current user on the context.

     

    Any help appreciated.  I'm trying to get this to work with IFD.  My application is in the ISV folder.  Thank you.

     

    This is my web.config:

    <?xml version="1.0"?>
    <configuration>
    	
    	<appSettings>
    
    
     <add key="OrganizationName" value="IEDC"/>
     <add key="WebSiteUrl" value="http://localhost:5555/IEDC"/>
     <add key="WebServiceUrl" value="http://localhost:5555/MSCRMServices/2007/CrmService.asmx"/>
     <add key="MetadataServiceUrl" value="http://localhost:5555/MSCRMServices/2007/MetadataService.asmx"/>
    	</appSettings>
    	<connectionStrings/>
    	<system.web>
    		<pages>
    			<controls>
    				<add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
    				<add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
    			</controls>
    		</pages>
    		<httpModules>
    			<clear/>
    			<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
    		</httpModules>
    	</system.web>
    </configuration>
    

     

    and this is the code I'm using:

     

    	 bool offline = false;
       string orgname = "IEDC";
       using (new CrmImpersonator())
       {
        CrmAuthenticationToken token;
        if (offline == true)
        {
         token = new CrmAuthenticationToken();
        }
        else
        {
         token = CrmAuthenticationToken.ExtractCrmAuthenticationToken(Context, orgname);
        }
        token.OrganizationName = orgname;
        token.AuthenticationType = 0;
    
        //Create the Service
        CrmService service = new CrmService();
        service.Credentials = System.Net.CredentialCache.DefaultCredentials;
        service.CrmAuthenticationTokenValue = token;
        service.Url = ConfigurationSettings.AppSettings["WebServiceUrl"];
    
        account account = new account();
        account.name = "Offline Impersonator: " + DateTime.Now.TimeOfDay.ToString();
        if (offline == false)
         account.ownerid = new Owner("systemuser", token.CallerId);
    
        service.Create(account);
    
        return service;
       }