2011-03-01 102 views
2

我有一個.Net 2.0 WinForm應用程序,它有一個WebBrowser控件用於訪問安全的網絡驅動器,這個網絡驅動器只允許訪問一些特殊帳戶和應用程序需要模擬一個閱讀器帳戶來閱讀PDF文件。訪問文件夾時WEbbrowser控件無法正常工作

我用LogonUser和應用程序能夠模擬讀取器帳戶來查看該文件夾下的文件名,但是當我使用webBrowser1.Navigate(新的Uri(filePath))m時,我得到訪問被拒絕。

所以經過研究,我知道我必須做我以前從未使用過的COM東西。好吧,在經過許多小時的在線和試驗/錯誤之後,我使用了IAuthenticate,IOleClientSite,IServiceProvider,我得到了一個解決方案,它可以很好地使用提供的用戶憑證訪問安全網站,它不會彈出框問用戶名和密碼,並將正確打開網站。

但是,如果我將網站URL替換爲安全文件路徑,則根本不起作用。

LogOnUser模擬東西實際上不需要Web瀏覽器訪問這裏的安全網站。但我不知道是否需要訪問文件夾。我試圖添加LogOnUser幷包裝webbrowser.Navigate(路徑),它沒有幫助。

誰能告訴我爲什麼這適用於網站而不是文件夾?

我使用的完整的測試代碼粘貼在這裏:

使用系統;使用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;使用System.Runtime.ConstrainedExecution的 ;使用System.Security的 ;

命名空間WebAuthenticateTest { #地區的COM接口

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

}

回答

1

的webrowser只查詢IAuthenticate進行託管MSHTML文檔時。如果文檔被隱藏,請嘗試使用明確的用戶憑據WNetAddConnection3