locked
Impersonation with Advanced Developer Extensions (microsoft.xrm) RRS feed

  • Question

  • Howdy,

    Does anyone know how to use impersonation from a WCF service using the CRM Advanced Developer Extensions? I would like to query the data service to return only the records of a given entity that the logged-in user has permissions to see.

    It's a big workaround to get the logged-in user from the advanced extensions anyway, but I hope that impersonation is possible. I know you can do it when you're building the CrmConnection directly in code yourself, but when you're using a data service, you don't have access to the CrmConnection.ImpersonatedUser property.

    Thanks!


    Web: http://invoc.net Blog: http://invoc.net/CRM_BPOS_Blog
    Monday, August 23, 2010 10:11 PM

Answers

  • Thanks William,

    I was aware of that, but unaware of how to perform that command when the identity of the user was only known by the Silverlight client side of the application, which was accessing CRM through a WCF data service.

    I've got it almost there - I created a "data service operation" (see http://blogs.msdn.com/b/marcelolr/archive/2008/01/21/service-operations-in-ado-net-data-services.aspx) and then began to make calls to this in my Silverlight code. However, the problem I'm having is that I'm not getting any data returned - but I think it's because of my Silverlight code. When I view this dataservice in a browser, I can input the proper query string parameters and view the results I expect.

    This code goes inside the data service class, parallel to the InitializeService method:

        [WebGet]
        public IEnumerable<opportunity> filteredopps(string userid, string org)
        {
          /*Define the connection with the impersonated user*/
          CrmConnection crmc = CrmConnection.Parse("Authentication Type=Passport; Server=https://" + org + ".crm.dynamics.com/" + org + "; User ID=myuser; Password=mypassword; Device ID=mydeviceid; Device Password=mydevicepassword");
          crmc.ImpersonatedUser = new Guid(userid);
          var crmOnline = new DataContext(crmc);
    
          
          List<opportunity> uplist = new List<opportunity>();
    
          crmOnline.UsingService(service =>
          {
    
    
            var query = from o in crmOnline.opportunityopportunities 
                  select o;
    
            foreach (opportunity thisopp in query)
            {
              uplist.Add(thisopp);
            }
          });
    
          return uplist;
        }
    

    Web: http://invoc.net
    Tuesday, August 31, 2010 4:07 PM

All replies

  • If i understand you correctly, all you need is to run the wcf service in a context of an impersonated user. That could be acheived by adding some impersonation behavior on the endpoint. Next you need to connect to CRM using advanced developer extensions API. That will require to create the datacontext with the proper connection string. Look in CRM sdk help documetion, (not in xrm api sdk help) there is an article for that named "Connect to the Microsoft Dynamics CRM server" which details all the possibilities of connection string. there are some examples in the bottom of this articel, may be you will need, "AuthenticationType=Integrated; Server=http://crm-server-name/crm-organization-name"

    When you query CRM with this connection, the dataservice should fetch the records that requesting user has permission to read etc according to the security roles assigned

     

    • Proposed as answer by ameed sheikh Monday, August 23, 2010 10:38 PM
    Monday, August 23, 2010 10:37 PM
  • Hey Ameed,

    Thanks for the response. I didn't understand the part about "adding some impersonation behavior on the endpoint", but here's my issue - were you envisioning this scenario?

    I'm building an application to be used by multiple users from multiple organizations. The user enters the application (it's a silverlight application, which is why the WCF data service is necessary) and I need to grab their org and userid to impersonate them. The xrm datacontext is created previous to all of this - when I create the WCF data service at compile time. As far as I can tell, when working with the Advanced Developer Extensions and the WCF data service, I'm not even able to define the connection string programatically - it has to be in the web.config. Which I don't think I can manipulate at run-time, especially not when everything happening at run-time is on the Silverlight end.

    So I'm at a loss as to how to run the WCF data service in the context of an impersonated user - were your suggestions anticipating this same situation?

    Thanks!


    Web: http://invoc.net
    Tuesday, August 24, 2010 1:32 AM
  • Hey Andy,

    CrmConnection.Parse can build CrmConnection at run-time.

    Tuesday, August 31, 2010 1:12 AM
  • Thanks William,

    I was aware of that, but unaware of how to perform that command when the identity of the user was only known by the Silverlight client side of the application, which was accessing CRM through a WCF data service.

    I've got it almost there - I created a "data service operation" (see http://blogs.msdn.com/b/marcelolr/archive/2008/01/21/service-operations-in-ado-net-data-services.aspx) and then began to make calls to this in my Silverlight code. However, the problem I'm having is that I'm not getting any data returned - but I think it's because of my Silverlight code. When I view this dataservice in a browser, I can input the proper query string parameters and view the results I expect.

    This code goes inside the data service class, parallel to the InitializeService method:

        [WebGet]
        public IEnumerable<opportunity> filteredopps(string userid, string org)
        {
          /*Define the connection with the impersonated user*/
          CrmConnection crmc = CrmConnection.Parse("Authentication Type=Passport; Server=https://" + org + ".crm.dynamics.com/" + org + "; User ID=myuser; Password=mypassword; Device ID=mydeviceid; Device Password=mydevicepassword");
          crmc.ImpersonatedUser = new Guid(userid);
          var crmOnline = new DataContext(crmc);
    
          
          List<opportunity> uplist = new List<opportunity>();
    
          crmOnline.UsingService(service =>
          {
    
    
            var query = from o in crmOnline.opportunityopportunities 
                  select o;
    
            foreach (opportunity thisopp in query)
            {
              uplist.Add(thisopp);
            }
          });
    
          return uplist;
        }
    

    Web: http://invoc.net
    Tuesday, August 31, 2010 4:07 PM