2

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;
            }
        }
    }
}
Community
  • 1
  • 1
elady
  • 535
  • 6
  • 22

0 Answers0