C# 访问文件文件夹时Webbrowser控件身份验证不工作

C# 访问文件文件夹时Webbrowser控件身份验证不工作,c#,winforms,authentication,browser,webbrowser-control,C#,Winforms,Authentication,Browser,Webbrowser Control,我有一个.Net 2.0 WinForm应用程序,它有一个WebBrowser控件,用于访问一个安全的网络驱动器,这个网络驱动器只允许访问几个特殊帐户,应用程序需要模拟一个读卡器帐户来读取PDF文件 我使用了LogonUser,应用程序能够模拟reader帐户来查看文件夹下的文件名,但是当我使用webBrowser1.Navigate(newURI(filePath))m时,我的访问被拒绝 所以经过研究,我知道我必须做一些我以前从未用过的东西。好的,经过几个小时的在线和尝试/错误后,我使用了IA

我有一个.Net 2.0 WinForm应用程序,它有一个WebBrowser控件,用于访问一个安全的网络驱动器,这个网络驱动器只允许访问几个特殊帐户,应用程序需要模拟一个读卡器帐户来读取PDF文件

我使用了LogonUser,应用程序能够模拟reader帐户来查看文件夹下的文件名,但是当我使用webBrowser1.Navigate(newURI(filePath))m时,我的访问被拒绝

所以经过研究,我知道我必须做一些我以前从未用过的东西。好的,经过几个小时的在线和尝试/错误后,我使用了IAuthenticate、IOleClientSite、IServiceProvider,我找到了结构,它可以很好地使用提供的用户凭据访问安全网站,它不会弹出框询问用户名和密码,并且会正确打开网站

然而,如果我将网站URL替换为安全的文件路径,它根本不起作用

webbrowser访问此处的安全网站实际上不需要LogOnUser模拟内容。但我不知道访问文件夹是否需要它。我尝试添加LogOnUser并包装webbrowser.Navigate(路径),但没有帮助

为什么这适用于网站而不是文件夹

我使用的完整测试代码粘贴在这里:

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Security.Principal; // WindowsImpersonationContext
using System.Security.Permissions; // PermissionSetAttribute
using Microsoft.Win32.SafeHandles;
using System.Runtime.ConstrainedExecution;
using System.Security;


namespace WebAuthenticateTest
{
    #region COM Interfaces

    [ComImport,
    Guid("00000112-0000-0000-C000-000000000046"),
    InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IOleObject
    {
        void SetClientSite(IOleClientSite pClientSite);
        void GetClientSite(IOleClientSite ppClientSite);
        void SetHostNames(object szContainerApp, object szContainerObj);
        void Close(uint dwSaveOption);
        void SetMoniker(uint dwWhichMoniker, object pmk);
        void GetMoniker(uint dwAssign, uint dwWhichMoniker, object ppmk);
        void InitFromData(IDataObject pDataObject, bool
        fCreation, uint dwReserved);
        void GetClipboardData(uint dwReserved, IDataObject ppDataObject);
        void DoVerb(uint iVerb, uint lpmsg, object pActiveSite,
        uint lindex, uint hwndParent, uint lprcPosRect);
        void EnumVerbs(object ppEnumOleVerb);
        void Update();
        void IsUpToDate();
        void GetUserClassID(uint pClsid);
        void GetUserType(uint dwFormOfType, uint pszUserType);
        void SetExtent(uint dwDrawAspect, uint psizel);
        void GetExtent(uint dwDrawAspect, uint psizel);
        void Advise(object pAdvSink, uint pdwConnection);
        void Unadvise(uint dwConnection);
        void EnumAdvise(object ppenumAdvise);
        void GetMiscStatus(uint dwAspect, uint pdwStatus);
        void SetColorScheme(object pLogpal);
    }

    [ComImport,
    Guid("00000118-0000-0000-C000-000000000046"),
    InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IOleClientSite
    {
        void SaveObject();
        void GetMoniker(uint dwAssign, uint dwWhichMoniker, object ppmk);
        void GetContainer(object ppContainer);
        void ShowObject();
        void OnShowWindow(bool fShow);
        void RequestNewObjectLayout();
    }

    [ComImport,
    GuidAttribute("6d5140c1-7436-11ce-8034-00aa006009fa"),
    InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown),
    ComVisible(false)]
    public interface IServiceProvider
    {
        [return: MarshalAs(UnmanagedType.I4)]
        [PreserveSig]
        int QueryService(ref Guid guidService, ref Guid riid, out IntPtr
        ppvObject);
    }

    [ComImport, GuidAttribute("79EAC9D0-BAF9-11CE-8C82-00AA004BA90B"),
    InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown),
    ComVisible(false)]
    public interface IAuthenticate
    {
        [return: MarshalAs(UnmanagedType.I4)]
        [PreserveSig]
        int Authenticate(ref IntPtr phwnd,
        ref IntPtr pszUsername,
        ref IntPtr pszPassword
        );
    }

    #endregion
    public partial class Form1 : Form, IOleClientSite, IServiceProvider, IAuthenticate
    {

        public static Guid IID_IAuthenticate = new Guid("79eac9d0-baf9-11ce-8c82-00aa004ba90b");
        public static Guid SID_IAuthenticate = new Guid("79eac9d0-baf9-11ce-8c82-00aa004ba90b");
        public const int INET_E_DEFAULT_ACTION = unchecked((int)0x800C0011);
        public const int S_OK = unchecked((int)0x00000000);
        private WindowsIdentity impersonateID; //impersonate user to access Picis PDF file folder.
        private bool logonFail = false;

        public Form1()
        {
            InitializeComponent();
            GetImpersonateID();

            string oURL = "about:blank";
            webBrowser1.Navigate(oURL);

            object obj = webBrowser1.ActiveXInstance;
            IOleObject oc = obj as IOleObject;
            oc.SetClientSite(this as IOleClientSite);

            System.IntPtr ppvServiceProvider;
            IServiceProvider sp = obj as IServiceProvider;
            sp.QueryService(ref SID_IAuthenticate, ref IID_IAuthenticate, out ppvServiceProvider);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            using (WindowsImpersonationContext impersonatedUser = impersonateID.Impersonate())
            {
                string oURL = "\\\\mydrive\\Reports\\Test\\Test.PDF";                
                webBrowser1.Navigate(new Uri(oURL));
            }
        }

        #region IOleClientSite Members

        public void SaveObject()
        {
            // TODO: Add Form1.SaveObject implementation
        }

        public void GetMoniker(uint dwAssign, uint dwWhichMoniker, object
        ppmk)
        {
            // TODO: Add Form1.GetMoniker implementation
        }

        public void GetContainer(object ppContainer)
        {
            ppContainer = this;
        }

        public void ShowObject()
        {
            // TODO: Add Form1.ShowObject implementation
        }

        public void OnShowWindow(bool fShow)
        {
            // TODO: Add Form1.OnShowWindow implementation
        }

        public void RequestNewObjectLayout()
        {
            // TODO: Add Form1.RequestNewObjectLayout implementation
        }

        #endregion

        #region IServiceProvider Members

        public int QueryService(ref Guid guidService, ref Guid riid, out IntPtr ppvObject)
        {
            int nRet = guidService.CompareTo(IID_IAuthenticate); // Zero returned if the compared objects are equal
            if (nRet == 0)
            {
                nRet = riid.CompareTo(IID_IAuthenticate); // Zero returned if the compared objects are equal
                if (nRet == 0)
                {
                    ppvObject = Marshal.GetComInterfaceForObject(this,
                    typeof(IAuthenticate));
                    return S_OK;
                }
            }
            ppvObject = new IntPtr();
            return INET_E_DEFAULT_ACTION;
        }

        #endregion

        #region IAuthenticate Members

        public int Authenticate(ref IntPtr phwnd, ref IntPtr pszUsername, ref IntPtr pszPassword)
        {
            IntPtr sUser = Marshal.StringToCoTaskMemAuto("Read");
            IntPtr sPassword = Marshal.StringToCoTaskMemAuto("mypwd");

            pszUsername = sUser;
            pszPassword = sPassword;
            return S_OK;
        }

        #endregion


        #region Impersonate  code
        //create  a impersonate context

        [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
            int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);

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

        /// <summary>
        /// Prepare a WindowsIdentity that has read access to the PDF file folder
        /// </summary>
        private void GetImpersonateID()
        {
            SafeTokenHandle safeTokenHandle = null;
            string user = "Read";
            string domainName = "mydomain";
            string pwd = "mypwd";
            try
            {
                const int LOGON32_PROVIDER_DEFAULT = 0;
                //This parameter causes LogonUser to create a primary token.
                const int LOGON32_LOGON_INTERACTIVE = 2;

                // Call LogonUser to obtain a handle to an access token.
                bool returnValue = LogonUser(user, domainName, pwd,
                    LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
                    out safeTokenHandle);

                if (returnValue)//user successfully logon
                {
                    impersonateID = new WindowsIdentity(safeTokenHandle.DangerousGetHandle());

                }
                else //error impersonate identity
                {
                    int ret = Marshal.GetLastWin32Error();
                    throw new System.ComponentModel.Win32Exception(ret);
                }
            }
            catch (Exception ex)
            {

                logonFail = true;
            }
            finally
            {
                if (safeTokenHandle != null)
                {
                    //safeTokenHandle.Dispose();
                    int i = 1;
                }
            }
        }

        #endregion
    }


    public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
    {
        private SafeTokenHandle()
            : base(true)
        {
        }

        [DllImport("kernel32.dll")]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        [SuppressUnmanagedCodeSecurity]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool CloseHandle(IntPtr handle);

        protected override bool ReleaseHandle()
        {
            return CloseHandle(handle);
        }
    }
}
使用系统;
使用System.Windows.Forms;
使用System.Runtime.InteropServices;
使用System.Runtime.CompilerServices;
使用System.Security.Principal;//WindowsImpersonationContext
使用System.Security.Permissions;//PermissionSetAttribute
使用Microsoft.Win32.SafeHandles;
使用System.Runtime.ConstrainedExecution;
使用系统安全;
命名空间WebAuthenticateTest
{
#区域COM接口
[ComImport,
Guid(“00000112-0000-0000-C000-0000000000 46”),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
公共接口IOleObject
{
void SetClientSite(IOleClientSite pClientSite);
作废GetClientSite(IOleClientSite-ppClientSite);
void SetHostNames(对象szContainerApp、对象szContainerObj);
无效关闭(uint dwSaveOption);
void SetMoniker(uint dwWhichMoniker,对象pmk);
void GetMoniker(uint-dwAssign、uint-dwWhichMoniker、object-ppmk);
void InitFromData(IDataObject pDataObject,bool
fCreation,uint(保留);
void GetClipboardData(uint dwReserved,IDataObject ppDataObject);
void DoVerb(uint-iVerb、uint-lpmsg、object-pActiveSite、,
uint lindex、uint hwndParent、uint lprcPosRect);
无效动词(宾语动词);
无效更新();
void是最新的();
无效GetUserClassID(uint pClsid);
void GetUserType(uint-dwFormOfType,uint-pszUserType);
无效设置范围(uint dwDrawAspect,uint psizel);
void GetExtent(uint dwDrawAspect,uint psizel);
无效通知(对象pAdvSink、uint pdwConnection);
无效不建议(uint DWT连接);
无效枚举建议(对象ppenumAdvise);
无效状态(uint dwAspect、uint pdwStatus);
void SetColorScheme(object pLogpal);
}
[ComImport,
Guid(“00000118-0000-0000-C000-0000000000 46”),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
公共接口IOleClientSite
{
void SaveObject();
void GetMoniker(uint-dwAssign、uint-dwWhichMoniker、object-ppmk);
void GetContainer(对象ppContainer);
void ShowObject();
void onshow窗口(bool fShow);
void RequestNewObjectLayout();
}
[ComImport,
指南属性(“6d5140c1-7436-11ce-8034-00aa006009fa”),
InterfaceTypeatAttribute(ComInterfaceType.InterfaceSiunknown),
ComVisible(假)]
公共接口IServiceProvider
{
[返回:Marshallas(UnmanagedType.I4)]
[信号]
int QueryService(ref Guid guidService,ref Guid riid,out IntPtr
ppvObject);
}
[ComImport,GuidatAttribute(“79EAC9D0-BAF9-11CE-8C82-00AA004BA90B”),
InterfaceTypeatAttribute(ComInterfaceType.InterfaceSiunknown),
ComVisible(假)]
公共接口IAuthenticate
{
[返回:Marshallas(UnmanagedType.I4)]
[信号]
int认证(参考IntPtr phwnd,
参考IntPtr pszUsername,
ref IntPtr pszPassword
);
}
#端区
公共部分类表单1:表单、IOleClientSite、IServiceProvider、IAAuthenticate
{
公共静态Guid IID_IAuthenticate=新Guid(“79eac9d0-baf9-11ce-8c82-00aa004ba90b”);
公共静态Guid SID_IAuthenticate=新Guid(“79eac9d0-baf9-11ce-8c82-00aa004ba90b”);
public const int INET_E_DEFAULT_ACTION=unchecked((int)0x800C0011);
public const int S_OK=unchecked((int)0x00000000);
私有WindowsIdentity impersonateID;//模拟用户以访问Picis PDF文件文件夹。
私有bool logonFail=false;
公共表格1()
{
初始化组件();
GetImpersonateID();
string oURL=“关于:空白”;
webBrowser1.导航(oURL);
object obj=webBrowser1.ActiveXInstance;
IOleObject oc=obj作为IOleObject;
oc.SetClientSite(这是IOleClientSite);
System.IntPtr ppvServiceProvider;
IServiceProvider sp=作为IServiceProvider的obj;
sp.QueryService(参考SID\u IAuthenticate、参考IID\u IAuthenticate、外部ppvServiceProvider);
}
私有无效按钮1\u单击(对象发送者,事件参数e)
{
使用(WindowsImpersonationContext impersonatedUser=impersonateID.Impersonate())
{
字符串oURL=“\\\\mydrive\\Reports\\Test\\Test.PDF”;
webBrowser1.导航(新Uri(oURL));
}
}
#区域IOleClientSite成员
公共void SaveObject()
{
//TODO:添加Form1.SaveObject impleme