C#为什么在执行Microsoft.SharePoint.Client.ClientContext.ExecuteQuery()时模拟已过期

时间:2013-12-11 13:39:02

标签: c# sharepoint permissions impersonation

我要做的是通过其他凭据(模拟)连接到SharePoint列表并打印其项目。

我正在使用this code进行模拟,并且几乎完美无缺,直到执行 clientContext.ExecuteQuery() 。我发现在此命令期间,模拟已过期(实际上这是我需要冒充的关键命令)。

我怎么能克服它?

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();


注:
要运行下面的代码,您需要:

  1. 添加对两个dll的引用(可以下载from here):

      

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

  2. 确保使用.NET 3.5(目前不高)

  3. 在以下行中插入实际值

    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 [ “的标题”]的ToString());

  4. (我在Win 7 64位上使用VS2010终极版)


    这是完整的代码:

    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;
                }
            }
        }
    }
    

0 个答案:

没有答案