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 AMHave you tried enabling impersonation to your web service?
Blog | SharePoint Field Notes Dev Tool | ClassMaster -
Wednesday, November 09, 2011 5:20 AM
-
Wednesday, November 09, 2011 5:29 AMYes 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
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
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
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
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
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

