How to do Impersonation of Clientcontext object using Client Object model in Sharepoint 2010

已答复 How to do Impersonation of Clientcontext object using Client Object model in Sharepoint 2010

  • Tuesday, November 08, 2011 12:04 PM
     
     

    Hi,

    I want to impersonate ClientContext object with current user's network credentials WITHOUT prompting or asking user for credentials.

    This code works

    ClientContext

     

    clientContext = new ClientContext("http://xyz");

    clientContext.Credentials =

    new System.Net.NetworkCredential("user","pwd","doamin");

    But I don't want to pass user and pwd. I tried following http://stackoverflow.com/questions/949340/getting-networkcredential-for-current-user-c link also but It did not work for me.

    I have a web service hosted in IIS and whenever I upload a file to Document library and retrieves it back it shows me App-pool account user and not the user who has uploaded the file. I think impersoantion will resolve this issue.

    Is there any workaround like in Server object model that we can pass the logged-in user's crededntials and impersonate the Clientcontext object.

    Thanks,

    Arsh

     

     

     

     

     

     


    Arsh

All Replies

  • Wednesday, November 09, 2011 12:15 AM
     
     
    Have you tried enabling impersonation to your web service?
    Blog | SharePoint Field Notes Dev Tool | ClassMaster
  • Wednesday, November 09, 2011 5:20 AM
     
      Has Code

    Have you tried:

    CredentialCache.DefaultNetworkCredentials


    @vrdmn | Email | LinkedIn | Blog
  • Wednesday, November 09, 2011 5:29 AM
     
     
    Yes I tried that. It did not work. This is what is there in the above link I shared
    Arsh
  • Wednesday, November 09, 2011 5:50 AM
     
      Has Code

    Thanks for the reply Steve.

    This is what you suggested:

    <behaviors>
    <serviceBehaviors>
    <behavior name="ServiceBehavior">
    <serviceMetadata httpGetEnabled="true" />
    <serviceDebug includeExceptionDetailInFaults="false" />
    <serviceAuthorization impersonateCallerForAllOperations="true" />
    </behavior>
    </serviceBehaviors>
    </behaviors>
    

    Impersonating web service will impersonate all my opeartions, whereas I only want to impersonate particular operation not all the operations. I even tried below code also .. but there I got the error:

    using (ServiceSecurityContext.Current.WindowsIdentity.Impersonate())
    {
    // You can get the impersonated user (original users identity) using
     WindowsIdentity.GetCurrent().Name, value) to verify current user.
    }
    
    System.IO.FileLoadException: The given assembly name or codebase, 'C:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\root\b0fb1a08\9d4741a7\assembly\dl3\e9a24c9e\cf3efb0b_e48fcc01\Microsoft.SharePoint.Client.Runtime.DLL', was invalid.

    Anyother way to do that

    Thanks

     


    Arsh
  • Wednesday, November 09, 2011 7:54 AM
     
      Has Code

    Hi,

    I think you have to retrieve a SharePoint user object first and pass it on to the service.

    This code return all the SP site users:

    ClientContext context = new Microsoft.SharePoint.Client.ClientContext(http://server:1234/SiteA/SiteB); 
    
     Web web = context.Web;
    
    List siteUserInfoList = web.SiteUserInfoList;  
    
    context.Load(siteUserInfoList);
    
    context.ExecuteQuery();
    
    CamlQuery query = new CamlQuery();
    
    query.ViewXml = "<View/>" ; 
     ListItemCollection lstUserColl = siteUserInfoList.GetItems(query); 
    


    Maybe you can create a CAML query for retrieving the user based on the current credentials. Pass it on to the web service, create a UserToken and then save the document.

    Something like this (web service code):

    var user = SPContext.Current.Web.AllUsers[User];
    var superToken = user.UserToken;
    using (var site = new SPSite(SPContext.Current.Web.Url, superToken)) {
    //here some code to save the document.
    }


    Hope it helps!

     


    Regards, Sjoukje

    Web: http://sjoukjezaal.com | LinkedIn: http://www.linkedin.com/in/sjoukjezaal | Twitter: @SjoukjeZaal

    Please click "Propose As Answer" if a post solves your problem or "Vote As Helpful" if a post has been useful to you.
  • Wednesday, November 09, 2011 3:12 PM
     
     Answered Has Code

    If you don't want your web service method to impersonate you can use the following code to use the application pool account when executing your code. All other web methods will use the impersonated user, then you won't need to do all the impersonation on the client side.

    private void ImpersonateCodeExecution()
    {
    
                WindowsImpersonationContext ctx = null;
    
                try
                {
                    if (!WindowsIdentity.GetCurrent().IsSystem)
                    {
                        ctx = WindowsIdentity.Impersonate(System.IntPtr.Zero);
    
                        //execute your code here
    
                    }
                }
                catch { }
                finally
                {
                    if (ctx != null)
                    {
                        ctx.Undo();
                    }
                
                }
     }
    


    Blog | SharePoint Field Notes Dev Tool | ClassMaster
    • Marked As Answer by Wayne Fan Friday, December 09, 2011 12:43 PM
    •  
  • Monday, November 14, 2011 11:11 AM
     
      Has Code

    Hi Steve,

    I am also looking for a solution to this impersonation thing . After going through all the above posts I tried the below code. but it is failing at the File.SaveBinary() method call.

    WindowsImpersonationContext ctx = null;
    if (!WindowsIdentity.GetCurrent().IsSystem)
    {
          ctx = WindowsIdentity.Impersonate(System.IntPtr.Zero);
    }
    using (ClientContext clientContext = new ClientContext(objDocument.workspaceUrl))
    {
      Site site = clientContext.Site;
      clientContext.Load(site, s => s.Url); //need url for some reasons
      clientContext.ExecuteQuery(); 
    .
    .
    .
     if (ctx != null)
    {
       ctx.Undo();// co'z while uploading the file I dont need appPool account.but need users account.
     }
    File.SaveBinaryDirect(clientContext, urlpart+ "/" + FileName,  stream, true);//Exception  : 401 UnAuthorized
    
    
    clientContext.ExecuteQuery();


     Could you please let me know how to correct this?

    Thanks.


    • Edited by PraTech Monday, November 14, 2011 11:13 AM Error is at SavebinaryDirect() cal. not at ExecuteQuesry() call.
    •  
  • Monday, November 14, 2011 3:32 PM
     
     Answered

    Hi Arsh,

    You don't need impersonation to set proper Author/Editor. You can do that with Client Object Model as well.

    Microsoft.SharePoint.Client.File theFile = web.GetFileByServerRelativeUrl(webPath);

    ListItem item = theFile.ListItemAllFields; // listItems[0];

    User theUser = web.EnsureUser(@"domain\name");

    clientContext.Load(theUser);

    clientContext.ExecuteQuery();

    item["Author"] = theUser;

    item["Editor"] = theUser;

    item.Update();

    clientContext.ExecuteQuery();

    Hope this helps.

    Regards,



    Vladimir
    MCTS, SharePoint tips blog: http://buyevich.blogspot.com
    • Marked As Answer by Wayne Fan Friday, December 09, 2011 12:42 PM
    •