- 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/
这个问题已经有答案了: Can the HWND from CreateWindow/CreateDialog be GetMessage'd from another thread? (7 个回答)
作为我的应用程序的一部分,我需要阻止来电。也就是说,当我的应用程序正在运行时,我将挂断所有调用并简单地通知调用者用户正忙或类似的事情。 我想用android SDK做这个,希望能支持Android 2
我正在尝试在 Android 上使用 Asmack API 实现一个简单的 XMPP 信使。这是代码: private final String XMPP_SERVER = "jabber.o
我刚刚安装了 watir,在 exec 之后 require 'watir-webdriver' browser = Watir::Browser.new :firefox 它只是打开浏览器,但一直挂
我有一个简单的问题,我需要找到波形的峰值。现在,我在使用 scipy 库中的 find_peaks_cwt 方法之前已经完成了此操作。然而,在这种情况下,我的程序在尝试找到峰值时只是挂起。我认为这与波
我不确定我的程序在哪里/如何挂起。我非常有信心它是在发送或接收链接中......但即使在互联网上搜索一些帮助并从我的教授那里获得帮助后,我仍然迷失,至于为什么这不起作用。 #include #inc
我正在尝试通过 appcelerator studio 为 android 应用程序商店打包我的应用程序,但在处理 javascript 文件后,控制台显示此错误 2017-04-17T22:47:3
const https = require("https"); const fs = require("fs"); const options = { hostname: "en.wikipedi
我有一个使用 Twilio 运行的应用程序。这个想法是你将调用一个电话号码,twilio 会接听并为你提供菜单选项。一旦你按下一个数字,它就会提交发布数据然后挂断(这部分工作正常)答案...我在他们的
Java 解决方案不是问题: public boolean killCall(Context context) { try { // Get the boring old Te
我试图在我的服务器上运行 jenkins,但我总是收到相同的消息,然后等待,等待,什么也没有。在官方网站上他们报告了这个问题,但我想问问是否有人知道如何解决这个问题,知道吗? 最佳答案 因为对我来说采
您好,在给定大量 json 对象的情况下,我在 NodeJS 上执行 HTTP 请求时遇到问题。给定小的 json 对象数组,请求工作正常。但是,如果我尝试增加 json 数组的大小,我会收到错误:套
我真的不知道发生了什么,直到今天早上我才检查这一切是否正常。我在 IDE 中看到的唯一异常(exception)是这个 IndexNotReadyException: Please change ca
我正在制作一个 ASP.NET (C#) 应用程序,它基本上是运行 Powershell 脚本以执行日常管理任务的网关。其中一些脚本使用 ActiveDirectory RSAT 模块,我发现其中一些
我是一名优秀的程序员,十分优秀!