问题描述
我有一个.Net 2.0 WinForm应用程序,它具有一个WebBrowser控件,该控件用于访问受保护的网络驱动器,该网络驱动器仅被授予对一些特殊帐户的访问权限,并且该应用程序需要模拟一个读取者帐户来读取. PDF文件.
I have a .Net 2.0 WinForm application, it has a WebBrowser control which is used to access a secured network drive, this network drive only granted access to a few special account and the application needs to impersonate one reader account to read the PDF file.
我使用了LogonUser,该应用程序可以模拟读者帐户来查看文件夹下的文件名,但是当我使用webBrowser1.Navigate(new Uri(filePath))m时,访问被拒绝了.
I used the LogonUser and the application was able to impersonate the reader account to see the file names under the folder, but then when I use webBrowser1.Navigate(new Uri(filePath))m, I got access denied.
因此,经过研究,我知道我必须做我以前从未使用过的COM东西.好的,经过数小时的在线和反复试验之后,我使用了IAuthenticate,IOleClientSite,IServiceProvider,将结构设计为可以使用提供的用户凭据访问安全网站的方式可以正常工作,不会弹出框询问输入用户名和密码,即可正确打开网站.
So after research, I know that I must do the COM stuff which I have never used before. Ok, after many hours online and trial/error, I used IAuthenticate,IOleClientSite, IServiceProvider, I got the struture worked out to where it will work fine for using the supplied user credential to access a secure website, it won't popup box ask for Username and password and will open the website correctly.
但是,如果我将网站URL替换为安全文件路径,则它根本不起作用.
Yet, if I replace the website URL to the secure file path, it doesn't work at all.
对于Web浏览器来说,实际上不需要LogOnUser模拟对象来访问安全的网站.但是我不知道访问文件夹是否需要它.我试图添加LogOnUser并包装webbrowser.Navigate(path),它没有帮助.
The LogOnUser impersonate stuff is actually not needed for the webbrowser to access the secure websites here. But I didn't know if it was needed for accessing file folders.I tried to add the LogOnUser and wrap the webbrowser.Navigate(path), It didn't help.
为什么这适用于网站而不适用于文件夹?
Why this works for website and not file folders?
我使用的完整测试代码粘贴在这里:
The full test code I used are pasted here:
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);
}
}
}
推荐答案
Webrowser仅在托管MSHTML文档时查询IAuthenticate.如果文档是defview,请尝试使用显式用户凭据登录WNetAddConnection3
The webrowser only query for IAuthenticate when hosting MSHTML document. If the document is defview, try WNetAddConnection3 with explicit user credentials
这篇关于访问文件夹时Webbrowser控件的身份验证不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!