- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在制作一个 ASP.NET (C#) 应用程序,它基本上是运行 Powershell 脚本以执行日常管理任务的网关。其中一些脚本使用 ActiveDirectory RSAT 模块,我发现其中一些 cmdlet 在通过网关调用时将无法正确运行,并且跟踪似乎暗示与域 Controller 的连接成功,但随后被关闭由 DC。
以下代码是一个 ASP.NET Web 表单,其中有一个文本输入来指定用户名。基本上,它执行以下操作:
通过将用户名读入表单的输出元素来确认成功。
protected void LookupButton_Click( object sender, EventArgs e ) {
WindowsImpersonationContext impersonationContext = ((WindowsIdentity)User.Identity).Impersonate();
Runspace runspace;
Pipeline pipe;
try {
runspace = new_runspace();
runspace.Open();
pipe = runspace.CreatePipeline();
Command cmd = new Command("Get-ADUser");
cmd.Parameters.Add(new CommandParameter("Identity", text_username.Text));
pipe.Commands.Add(cmd);
PSObject ps_out = pipe.Invoke().First();
output.Text = ps_out.Properties["Name"].Value.ToString();
}
catch( Exception ex ) {
error.Text = ex.ToString();
}
finally {
impersonationContext.Undo();
}
}
private Runspace new_runspace( ) {
InitialSessionState init_state = InitialSessionState.CreateDefault();
init_state.ThreadOptions = PSThreadOptions.UseCurrentThread;
init_state.ImportPSModule(new[] { "ActiveDirectory" });
return RunspaceFactory.CreateRunspace(init_state);
}
有趣的部分是在 catch block 中暴露的错误消息中的具体措辞(强调我的):
System.Management.Automation.CmdletInvocationException: Unable to contact the server. This may be because this server does not exist, it is currently down, or it does not have the Active Directory Web Services running. ---> Microsoft.ActiveDirectory.Management.ADServerDownException: Unable to contact the server. This may be because this server does not exist, it is currently down, or it does not have the Active Directory Web Services running. ---> System.ServiceModel.CommunicationException: The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:01:59.6870000'. ---> System.IO.IOException: The read operation failed, see inner exception. ---> System.ServiceModel.CommunicationException: The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:01:59.6870000'. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
上层异常提示超时,但下层异常提示没有超时(命令返回只需要几秒)。在无法访问服务器的情况下,最低级别的异常消息说明了同样多的内容,但这种特定的措辞让我觉得这里存在某种身份验证(或其他安全)问题。
2013 年 2 月 19 日更新:使用描述的模拟方法时 here ,脚本按预期运行。这让我觉得问题可能是 Windows 身份验证提供的 WindowsIdentity 对象可能不适合本质上对 AD 进行 RPC 调用的脚本。不幸的是,我真的不希望放弃 Windows 身份验证,因为我必须在我的应用程序代码中处理用户的密码(这不是我想要的责任)。
我无法找到任何关于 Windows 身份验证究竟在做什么或允许使用它进行何种模拟的文档。是否可以在使用 Windows 身份验证时执行此操作,还是我必须要求用户提供密码?
最佳答案
此问题的根本原因是,当您在 IIS 中使用 Windows 身份验证时,安全 token 仅对 Web 客户端计算机到 Web 服务器计算机的身份验证有效。相同的 token 对于向任何其他机器验证 Web 服务器机器是无效的,而这正是我的应用程序试图做的:
将其称为 Kerberos 的“副作用”并不完全正确,但起初对我来说并不明显,尽管事后看来很明显。我希望有人可以从这些信息中受益。
此问题的解决方案是让应用程序生成自己的安全 token ,然后通过对 LogonUser() 进行 API 调用,可以使用该 token 作为 Web 用户对其他机器上的服务进行身份验证。 .您的应用程序代码将需要访问用户的明文密码,这可以通过在 IIS 中仅启用 HTTP 基本身份验证来实现。 Web 服务器仍将执行相同的身份验证和授权规则,但用户名和密码都将可供您的应用程序代码使用。请记住,这些凭据会以明文方式传输到 Web 服务器,因此在生产中使用它之前,您将需要 SSL。
我根据描述的过程创建了一个小的助手类 here这促进了这个过程。这是一个简短的演示:
登录助手:
public class IdentityHelper {
[DllImport("advapi32.dll")]
private static extern int LogonUserA( String lpszUserName, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken );
[DllImport("advapi32.dll",
CharSet = CharSet.Auto,
SetLastError = true)]
private static extern int DuplicateToken( IntPtr hToken, int impersonationLevel, ref IntPtr hNewToken );
[DllImport("kernel32.dll",
CharSet = CharSet.Auto)]
private static extern bool CloseHandle( IntPtr handle );
public const int LOGON32_LOGON_INTERACTIVE = 2;
public const int LOGON32_PROVIDER_DEFAULT = 0;
public const int IMPERSONATION_LEVEL_IMPERSONATE = 2;
public static WindowsIdentity Logon( string username, string password, string domain = "" ) {
IntPtr token = IntPtr.Zero;
WindowsIdentity wid = null;
if( domain == "" ) {
split_username(username, ref username, ref domain);
}
if( LogonUserA(username, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token) != 0 ) {
wid = WIDFromToken(token);
}
if( token != IntPtr.Zero ) CloseHandle(token);
return wid;
}
public static WindowsIdentity WIDFromToken( IntPtr src ) {
WindowsIdentity wid = null;
IntPtr token = IntPtr.Zero;
if( DuplicateToken(src, IMPERSONATION_LEVEL_IMPERSONATE, ref token) != 0 ) {
wid = new WindowsIdentity(token);
}
if( token != IntPtr.Zero ) CloseHandle(token);
return wid;
}
private static void split_username( string username, ref string username_out, ref string domain_out ) {
string[] composite_username = username.Split(new char[] { '\\' });
if( composite_username.Length == 2 ) {
domain_out = composite_username[0];
username_out = composite_username[1];
}
}
}
Powershell 辅助类:
public class PSHelper {
public static Runspace new_runspace() {
InitialSessionState init_state = InitialSessionState.CreateDefault();
init_state.ThreadOptions = PSThreadOptions.UseCurrentThread;
init_state.ImportPSModule(new[] { "ActiveDirectory" });
return RunspaceFactory.CreateRunspace(init_state);
}
}
ASP.NET 表单处理程序:
protected void LookupButton_Click( object sender, EventArgs e ) {
string outp = "";
WindowsIdentity wid = IdentityHelper.Logon(Request["AUTH_USER"], Request["AUTH_PASSWORD"]);
using( wid.Impersonate() ) {
Runspace runspace;
Pipeline pipe;
runspace = PSHelper.new_runspace();
runspace.Open();
pipe = runspace.CreatePipeline();
Command cmd = new Command("Get-ADUser");
cmd.Parameters.Add(new CommandParameter("Identity", text_username.Text));
pipe.Commands.Add(cmd);
outp = pipe.Invoke().First().Properties["Name"].Value.ToString();
}
output.Text = outp;
}
关于c# - ASP.NET 托管 Active Directory RSAT powershell 脚本--DC 挂断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14946575/
我有 powershell 脚本。通过调度程序,我运行 bat 文件,该文件运行 PS1 文件。 BAT文件 Powershell.exe -executionpolicy remotesigned
什么更快? 或者 $.getScript('../js/SOME.js', function (){ ... // with $.ajaxSetup({ cache: true });
需要bash脚本来显示文件 #!/bin/bash my_ls() { # save current directory then cd to "$1" pushd "$1" >/dev/nu
我有一个输入 csv 文件,实际上我需要在输入文件中选择第 2 列和第 3 列值,并且需要转换两个值的时区(从 PT 到 CT),转换后我需要替换转换后的时区值到文件。 注意: 所有输入日期值都在太平
我正在使用/etc/init.d/httpd 作为 init.d 脚本的模板。我了解文件中发生的所有内容,但以下行除外: LANG=$HTTPD_LANG daemon --pidfile=${pid
我有以下选择: python runscript.py -O start -a "-a "\"-o \\\"-f/dev/sda1 -b256k -Q8\\\" -l test -p maim\""
我对 shell 脚本完全陌生,但我需要编写一个 shell 脚本来检查文件是否存在,然后移动到另一个位置 这是我写的: 一旦设备崩溃,我就会在/storage/sdcard1/1 中收集日志 #!/
我正在使用 bash 脚本从文本文件中读取数据。 数据: 04:31 Alex M.O.R.P.H. & Natalie Gioia - My Heaven http://goo.gl/rMOa2q
这是单击按钮时运行的 javascript 的结尾 xmlObj.open ('GET', /ajax.php, true); xmlObj.send (''); } 所以这会执行根目录中的php脚本
关闭。这个问题需要debugging details .它目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and th
我需要将文件转换为可读流以通过 api 上传,有一个使用 fs.createReadStream 的 Node js 示例。任何人都可以告诉我上述声明的 python 等价物是什么? 例子 const
我有一个 shell 脚本 cron,它从同一目录调用 python 脚本,但是当这个 cron 执行时,我没有从我的 python 脚本中获得预期的输出,当我手动执行它时,我的 python 脚本的
如何使 XMLHttpRequest (ajax) 调用的 php 脚本安全。 我的意思是,不让 PHP 文件通过直接 url 运行,只能通过脚本从我的页面调用(我不想向未登录的用户显示数据库结果,并
我正在尝试添加以下内容 我正在使用经典的 asp。但我不断收到的错误是“一个脚本 block 不能放在另一个脚本 block 内。”我尝试了此处的 document.write 技术:Javasc
如何从另一个 PHP 脚本(如批处理文件)中运行多个 PHP 脚本?如果我了解 include 在做什么,我认为 include 不会起作用;因为我正在运行的每个文件都会重新声明一些相同的函数等。我想
我想创建具有动态内容的网页。我有一个 HTML 页面,我想从中调用一个 lua 脚本 如何调用 lua 脚本? ? ? 从中检索数据?我可以做类似的事情吗: int xx = 0; xx
我删除了我的第一个问题,并重新编写了更多细节和附加 jSfiddle domos。 我有一个脚本,它运行查询并返回数据,然后填充表。表中的行自动循环滚动。所有这些工作正常,并通过使用以下代码完成。然而
我尝试使用 amp 脚本,但收到此错误: “[amp-script] 脚本哈希未找到。amp-script[script="hello-world"].js 必须在元[name="amp-script
我有一个读取输入的 Shell 脚本 #!/bin/bash echo "Type the year that you want to check (4 digits), followed by [E
我正在从 nodejs 调用 Lua 脚本。我想传递一个数组作为参数。我在 Lua 中解析该数组时遇到问题。 下面是一个例子: var script = 'local actorlist = ARGV
我是一名优秀的程序员,十分优秀!