3

What I’m trying to do is to connect to SharePoint list by other credentials (impersonation) and print its items.

I’m using this code for the impersonation, and it works almost perfectly, until clientContext.ExecuteQuery() is performed. I found that during this command, the impersonation is expired (actually this is the critical command I need to impersonate for).

How can I get over it?

CredentialsController.Impersonator imp = null;
imp = new CredentialsController.Impersonator("myUsername", "myDomain", "myPassword");

CamlQuery camlQuery = new CamlQuery();
camlQuery.ViewXml = query;
listItemCollection = selectedList.GetItems(camlQuery);
clientContext.Load(listItemCollection);
clientContext.ExecuteQuery(); // ****This line cancels the impersonation****

imp.UndoImpersonation();




Notes:
To run the code below, you need to:

  1. Add reference to two dlls (Can be downloaded from here):

    Microsoft.SharePoint.Client.dll
    Microsoft.SharePoint.Client.Runtime.dll

  2. Make sure that you use .NET 3.5 (currently not higher)

  3. Insert real values in the following lines

    string siteUrl = "https://SP_Server.com/sites/some_site/";
    string listID = "3c84e774-86c4-4b45-8a0a-437526e8728f";
    imp = new CredentialsController.Impersonator("myUsername", "myDomain", "myPassword");
    Console.WriteLine(oListItem["Title"].ToString());

(I'm using VS2010 ultimate on Win 7 64 bit)



Here is the complete code:

using System;
using System.Collections.Generic;
using System.Security.Principal;
using System.ComponentModel;
using System.Runtime.InteropServices;
using Microsoft.SharePoint.Client;

namespace WhereAmILoggedIn
{
    class SharePointGetter
    {
        static void Main()
        {
            string siteUrl = "https://SP_Server/sites/some_site/";
            string query = "<View></View>";
            string listID = "3c84e774-86c4-4b45-8a0a-437526e8728f";

            CredentialsController.Impersonator imp = null;
            imp = new CredentialsController.Impersonator("myUsername", "myDomain", "myPassword");

            ListItemCollection listItemCollection;
            try
            {
                Microsoft.SharePoint.Client.ClientContext clientContext = new ClientContext(siteUrl);
                Microsoft.SharePoint.Client.List selectedList = clientContext.Web.Lists.GetById(new Guid(listID));

                CamlQuery camlQuery = new CamlQuery();
                camlQuery.ViewXml = query;
                listItemCollection = selectedList.GetItems(camlQuery);
                clientContext.Load(listItemCollection);

                Console.WriteLine(Convert.ToString(WindowsIdentity.GetCurrent().Name)); //************ Before
                clientContext.ExecuteQuery();
                Console.WriteLine(Convert.ToString(WindowsIdentity.GetCurrent().Name)); //************ After
            }
            catch (Exception)
            {
                throw new Exception("Access denied", new Exception("Are you missing permissions?"));
            }


            foreach (ListItem oListItem in listItemCollection)
            {
                Console.WriteLine(oListItem["Title"].ToString());
            }

            if (imp != null)
                imp.UndoImpersonation();
        }
    }

    class CredentialsController
    {
        public enum LogonType
        {
            LOGON32_LOGON_INTERACTIVE = 2,
            LOGON32_LOGON_NETWORK = 3,
            LOGON32_LOGON_BATCH = 4,
            LOGON32_LOGON_SERVICE = 5,
            LOGON32_LOGON_UNLOCK = 7,
            LOGON32_LOGON_NETWORK_CLEARTEXT = 8, // Win2K or higher
            LOGON32_LOGON_NEW_CREDENTIALS = 9 // Win2K or higher
        };

        public enum LogonProvider
        {
            LOGON32_PROVIDER_DEFAULT = 0,
            LOGON32_PROVIDER_WINNT35 = 1,
            LOGON32_PROVIDER_WINNT40 = 2,
            LOGON32_PROVIDER_WINNT50 = 3
        };

        public enum ImpersonationLevel
        {
            SecurityAnonymous = 0,
            SecurityIdentification = 1,
            SecurityImpersonation = 2,
            SecurityDelegation = 3
        }

        class Win32NativeMethods
        {
            [DllImport("advapi32.dll", SetLastError = true)]
            public static extern int LogonUser(string lpszUserName,
                 string lpszDomain,
                 string lpszPassword,
                 int dwLogonType,
                 int dwLogonProvider,
                 ref IntPtr phToken);

            [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            public static extern int DuplicateToken(IntPtr hToken,
                  int impersonationLevel,
                  ref IntPtr hNewToken);

            [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            public static extern bool RevertToSelf();

            [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
            public static extern bool CloseHandle(IntPtr handle);
        }


        public class Impersonator : IDisposable
        {
            private WindowsImpersonationContext _wic;


            public Impersonator(string userName, string domainName, string password, LogonType logonType, LogonProvider logonProvider)
            {
                Impersonate(userName, domainName, password, logonType, logonProvider);
            }

            public Impersonator(string userName, string domainName, string password)
            {
                Impersonate(userName, domainName, password, LogonType.LOGON32_LOGON_INTERACTIVE, LogonProvider.LOGON32_PROVIDER_DEFAULT);
            }

            public Impersonator()
            { }

            public void Dispose()
            {
                UndoImpersonation();
            }

            public void Impersonate(string userName, string domainName, string password)
            {
                Impersonate(userName, domainName, password, LogonType.LOGON32_LOGON_INTERACTIVE, LogonProvider.LOGON32_PROVIDER_DEFAULT);
            }

            public void Impersonate(string userName, string domainName, string password, LogonType logonType, LogonProvider logonProvider)
            {
                UndoImpersonation();

                IntPtr logonToken = IntPtr.Zero;
                IntPtr logonTokenDuplicate = IntPtr.Zero;
                try
                {
                    // revert to the application pool identity, saving the identity of the current requestor
                    _wic = WindowsIdentity.Impersonate(IntPtr.Zero);

                    // do logon & impersonate
                    if (Win32NativeMethods.LogonUser(userName,
                        domainName,
                        password,
                        (int)logonType,
                        (int)logonProvider,
                        ref logonToken) != 0)
                    {
                        if (Win32NativeMethods.DuplicateToken(logonToken, (int)ImpersonationLevel.SecurityImpersonation, ref logonTokenDuplicate) != 0)
                        {
                            var wi = new WindowsIdentity(logonTokenDuplicate);
                            wi.Impersonate(); // discard the returned identity context (which is the context of the application pool)
                        }
                        else
                            throw new Win32Exception(Marshal.GetLastWin32Error());
                    }
                    else
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                }
                finally
                {
                    if (logonToken != IntPtr.Zero)
                        Win32NativeMethods.CloseHandle(logonToken);

                    if (logonTokenDuplicate != IntPtr.Zero)
                        Win32NativeMethods.CloseHandle(logonTokenDuplicate);
                }
            }

            /// Stops impersonation.
            public void UndoImpersonation()
            {
                // restore saved requestor identity
                if (_wic != null)
                    _wic.Undo();
                _wic = null;
            }
        }
    }
}
  • What happens if you run the program with the credentials of the user you are trying to impersonate? – Wout Dec 24 '13 at 6:22
  • @W0ut, In this case, there is no really impersonation, the credentials before and after the impersonation are the same, thus everything is going fine. – elady Dec 29 '13 at 19:36
1

Is this code running on the SharePoint server? If so try using the default SharePoint API and the runwithelevatedpriviledges rather than an impersonator and clientcontext.

http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spsecurity.runwithelevatedprivileges.aspx

|improve this answer|||||
  • No, this code is running on every client PC without SharePoint server installed. – elady Dec 29 '13 at 19:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.