Asp classic FileSystemObject-CScript.exe的文件权限说明了一件事,经典ASP说明了另一件事
我有一个用JScript编写的经典ASP页面,它使用Scripting.FileSystemObject将文件保存到网络共享,但它不起作用。(“拒绝许可”) ASP页正在IIS下使用Windows身份验证运行,并启用了模拟 如果我通过CScript.exe在本地运行以下代码块:Asp classic FileSystemObject-CScript.exe的文件权限说明了一件事,经典ASP说明了另一件事,asp-classic,permissions,wsh,filesystemobject,Asp Classic,Permissions,Wsh,Filesystemobject,我有一个用JScript编写的经典ASP页面,它使用Scripting.FileSystemObject将文件保存到网络共享,但它不起作用。(“拒绝许可”) ASP页正在IIS下使用Windows身份验证运行,并启用了模拟 如果我通过CScript.exe在本地运行以下代码块: var objNet = new ActiveXObject("WScript.Network"); WScript.Echo(objNet.ComputerName); WScript.Echo(objNet.User
var objNet = new ActiveXObject("WScript.Network");
WScript.Echo(objNet.ComputerName);
WScript.Echo(objNet.UserName);
WScript.Echo(objNet.UserDomain);
var fso = new ActiveXObject("Scripting.FileSystemObject");
var path = "\\\\myserver\\my_share\\some_path";
if (fso.FolderExists(path)) {
WScript.Echo("Yes");
} else {
WScript.Echo("No");
}
我得到(预期)输出:
如果我运行与.ASP页面相同的代码,将Response.Write替换为WScript.Echo,则会得到以下输出:
MY_COMPUTER
dylan.beattie
MYDOMAIN
No
现在-我的理解是WScript.Network对象将检索实际运行代码的线程的当前安全凭据。如果这是正确的-那么为什么同一个域上的同一个用户从CScript.exe和ASP获得不同的结果?如果我的ASP代码以dylan.beattie的身份运行,那么为什么我看不到网络共享?如果它不是以dylan.beattie的身份运行,为什么WScript.Network会认为它是?在模拟下,您只能访问本地计算机上的安全资源,无法通过网络访问任何内容 在Windows上,当您作为模拟用户运行时,您是在所谓的网络令牌下运行的。此令牌具有本地计算机访问的用户凭据,但没有远程访问的凭据。因此,当您访问网络共享时,您实际上是以匿名用户的身份访问它 当您在桌面上运行进程(如CScript.exe)时,您是在交互式用户令牌下运行的。此令牌具有本地和远程访问的完整凭据,因此您可以访问网络共享
为了在模拟Windows用户时访问远程资源,必须使用委派而不是模拟。这将涉及对Active directory的一些更改,以允许计算机和/或域中的用户进行委派。这可能是一种安全风险,因此应仔细检查。您的问题很清楚。在当前的实现中,您只模拟用户,没有委派。我不想重复斯蒂芬·马丁已经写过的信息。我只想添加至少三个解决方案。斯蒂芬·马丁(Stephen Martin)提出的经典授权方式只是一种方式。您可以在此处阅读更多方法:。我认为解决问题有三种切实可行的方法:
DuplicateToken
或DuplicateTokenEx
执行此操作WindowsIdentity wi=new-WindowsIdentity(identity)代码>
hUserToken
的令牌,并调用APIImpersonateLoggedOnUser(hUserToken)代码>
要返回到原始进程令牌(仅适用于当前线程),可以调用RevertToSelf()
函数。用户的令牌将被IIS接收并已为您模拟,因为您已这样配置了网站。要返回到原始进程令牌,您应该在自定义COM组件中实现函数RevertToSelf()
的调用。也许,如果您不需要在ASP页面中执行更多操作,这就足够了,但我建议您在对文件进行操作之前要更加小心,将当前用户令牌保存在一个变量中。然后使用文件系统执行所有操作,最后将用户令牌重新分配回当前线程。您可以针对SetThreadToken(NULL,hUserToken)将模拟令牌分配给线程代码>。要提供(保存)当前线程令牌(在您的情况下为用户令牌),您可以使用OpenThreadToken
API。它必须起作用
更新2:可能在一个ASP页面的结尾使用RevertToSelf()
函数,对您来说已经可以了。相应的C#代码可以是:
在C#中创建一个名为LoginAdmin
的“类库”类型的新项目。过去的
MY_COMPUTER
dylan.beattie
MYDOMAIN
No
using System;
using System.Runtime.InteropServices;
namespace LoginAdmin {
[InterfaceTypeAttribute (ComInterfaceType.InterfaceIsDual)]
public interface IUserImpersonate {
[DispId(1)]
bool RevertToSelf ();
}
internal static class NativeMethods {
[DllImport ("advapi32.dll", SetLastError = true)]
internal static extern bool RevertToSelf ();
}
[ClassInterface (ClassInterfaceType.AutoDual)]
public class UserImpersonate : IUserImpersonate {
public UserImpersonate () { }
public bool RevertToSelf () {
return NativeMethods.RevertToSelf();
}
}
}
[assembly: ComVisible (true)]
<%@ Language="javascript" %>
<html><body>
<% var objNet = Server.CreateObject("WScript.Network");
Response.Write("Current user: ");Response.Write(objNet.UserName);Response.Write("<br/>");
Response.Write("Current user's domain: ");Response.Write(objNet.UserDomain);Response.Write("<br/>");
var objLoginAdmin = Server.CreateObject("LoginAdmin.UserImpersonate");
var isOK = objLoginAdmin.RevertToSelf();
if (isOK)
Response.Write("RevertToSelf return true<br/>");
else
Response.Write("RevertToSelf return false<br/>");
Response.Write("One more time after RevertToSelf()<br/>");
Response.Write("Current user: ");Response.Write(objNet.UserName);Response.Write("<br/>");
Response.Write("Current user's domain: ");Response.Write(objNet.UserDomain);Response.Write("<br/>");
var fso = Server.CreateObject("Scripting.FileSystemObject");
var path = "\\\\mk01\\C\\Oleg";
if (fso.FolderExists(path)) {
Response.Write("Yes");
} else {
Response.Write("No");
}%>
</body></html>
Current user: Oleg
Current user's domain: WORKGROUP
RevertToSelf return true
One more time after RevertToSelf()
Current user: DefaultAppPool
Current user's domain: WORKGROUP
Yes