有没有办法告诉我的代码以不同的用户身份运行?
我通过PInvoke调用NetUserSetInfo,我需要将其称为不同的用户.有没有办法做到这一点?
如何在不同用户的安全上下文中启动线程?当进程正常启动一个线程时,安全上下文也会被传递但是如何在不同安全上下文中使用不同用户的主体启动一个线程?
我使用类似下面的方法来模拟我的代码中的用户:
在另一个类中,我需要找出当前用户(如"mydomain\moose"),但我不知道我是否正在冒充其他用户.
如果我冒充某人,我如何获得用户名?
System.Environment.UserName和System.Security.Principal.WindowsIdentity.GetCurrent().Name都返回原始用户,而不是当前模拟的用户.
更多细节:
我正在进行此模拟,以便我可以访问用户通常无权访问的netowrk共享中的某些文件.
如果我使用登录类型的LOGON32_LOGON_INTERACTIVE,我确实看到了新用户,但我无法访问网络共享.如果我使用登录类型的LOGON32_LOGON_NEW_CREDENTIALS(值为9),我可以访问网络共享但我没有在Environment.UserName中看到新用户.
在我的WPF应用程序中,我希望允许管理员使用集成安全性为各种其他用户测试数据库连接.所以我有一个表单,允许管理员输入域名,用户名和密码,然后测试它.我能够安全地处理密码,直到我打电话LogonUser给advapi32.dll它需要一个string password
LogonUser(UserName, Domain, Password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref UserHandle)
我编写了一个实用程序函数,它将SecureString转换为尽可能安全的字符串,然后在LogonUser调用中将其调用密码:
LogonUser(UserName, Domain, Helper.ConvertSafely(Password), LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref UserHandle)
由于LogonUser的签名采用字符串,除非LogonUser在执行时正确地处理密码,否则在调用返回后它仍然可以在我的调用堆栈中以纯文本形式存在.是否有一种更安全的方式来冒充用户,在这种情况下,我可以确信PW一直是安全的?
基本上我只需要一个WindowsImpersonationContext但是我想在没有密码的情况下以纯文本形式获取它.
在我掌握Windows中用户模仿的细微差别的过程中,我首先遇到了一个关于冒充远程数据库的问题(请参阅此SO问题),但我终于弄明白了.我的下一个障碍是撤消/取消/恢复(选择你最喜欢的动词)模仿.
我尝试了几个不同的模拟库,这对我来说是可信的:
结果与两个库相同.最佳实践要求使用LOGON32_LOGON_NEW_CREDENTIALS登录类型(请参阅Windows API LogonUser函数)进行远程数据库连接.当我这样做时,这是我的示例代码产生的:
// SCENARIO A
BEGIN impersonation.
Local user = MyDomain\MyUser
DB reports: MyDomain\ImpersonatedUser
END impersonation.
Local user = MyDomain\MyUser
DB reports: MyDomain\ImpersonatedUser << NOT EXPECTED HERE!!
我找到的唯一解决方法是使用LOGON32_LOGON_INTERACTIVE登录类型,然后我得到:
// SCENARIO B
BEGIN impersonation.
Local user = MyDomain\ImpersonatedUser << EXPECTED, BUT NOT WANTED!
DB reports: MyDomain\ImpersonatedUser
END impersonation.
Local user = MyDomain\MyUser
DB reports: MyDomain\MyUser
从WindowsImpersonationContext.Undo方法的简洁描述来看,它似乎应该在方案A中起作用.
是否可以使用LOGON32_LOGON_NEW_CREDENTIALS登录类型进行恢复?
我正在尝试使用ServerManager.OpenRemote(来自Microsoft.Web.Administration),但无法找到有关如何从当前用户提供不同凭据的文档.我尝试过SimpleImpersonation(来自你如何在.NET中进行模拟?)它给了我同样的错误:
System.UnauthorizedAccessException - 由于以下错误,从机器[...]检索具有CLSID {2B72133B-3F5B-4602-8952-803546CE3344}的远程组件的COM类工厂失败:80070005 [...]."
远程计算机上的防火墙已关闭.UAC已禁用.
我在使用没有指定用户的模拟访问Web服务时遇到问题.
作品:
     <identity impersonate="true" userName="DOMAIN\USERNAME" password="MyPassword" />
不起作用
<identity impersonate="true" /> 
在调试时,我使用下面的代码来验证正在使用的域和用户名,它们是.
System.Security.Principal.WindowsIdentity.GetCurrent().Name;
这是我的web.config的更多内容
<authentication mode="Windows" />
<identity impersonate="true" /> 
<authorization>
  <allow users="*" />
  <deny users="?"/>
</authorization>
我正在登录提示,图片如下
任何想法为什么它只有在我在web.config中指定用户时才有效?我使用与Domain\Username放入<identity impersonate="true" userName="DOMAIN\USERNAME" password="MyPassword" />中相同的密码登录.我尝试过多个帐户,当我将凭据放入web.config但没有使用身份设置<identity impersonate="true" />和登录时,它们都能正常工作.
编辑 
远程服务器返回错误:(403)禁止. 

编辑2 一切正常,在调试时,并在包含它托管的IIS的服务器上点击服务,我尝试了多个帐户,他们都工作.一切都在同一个领域
我有一个带有清单的应用程序需要以管理员身份运行,但应用程序的一部分是使用WNetAddConnection2映射驱动器,我相信由于凭据等原因,它需要在普通用户上下文中运行.有没有办法执行此操作普通用户上下文中的一些代码,无需创建单独的进程.
编辑
从我的评论到目前为止,但它不起作用.我预计它不会因为我真的不明白我应该如何使用它.如果我打开一个新问题,也许最好?
class Program
{
    [DllImport("advapi32.DLL")]
    public static extern bool ImpersonateLoggedOnUser(IntPtr hToken);
    [DllImport("advapi32.DLL")]
    public static extern bool RevertToSelf();
    static void Main(string[] args)
    {
        IntPtr phToken = IntPtr.Zero;
        ImpersonateLoggedOnUser(phToken);
        MapDrives();
        RevertToSelf();
    }
}
编辑
如果当前用户具有管理员权限,那么主进程将使用清单提升,在提升的代码中我想在用户非提升空间中运行命令,因为这似乎具有不同的环境变量等.我相信曾经线程启动它不能改变自己,它需要运行一个新的.
我试图从ASP.Net应用程序的调用者那里获得当前的WindowsIdentity而不进行模拟.
阅读一些文章后我的设置是:
出于测试目的,我编写了以下日志语句
m_techLogger.Warn(string.Format("Request[LOGON_USER] {0}", Request["LOGON_USER"]));
m_techLogger.Warn(string.Format("Request.LogonUserIdentity {0}", Request.LogonUserIdentity.Name));
m_techLogger.Warn(string.Format("HttpContext.Current.User.Identity {0}", HttpContext.Current.User.Identity.Name));
m_techLogger.Warn(string.Format("WindowsIdentity.GetCurrent() {0}", WindowsIdentity.GetCurrent().Name));
这些陈述返回以下内容
2015-04-23 10:47:19,628 [7] WARN  - Request[LOGON_USER] DOMAIN\User
2015-04-23 10:47:19,681 [7] WARN  - Request.LogonUserIdentity NT AUTHORITY\SYSTEM
2015-04-23 10:47:19,681 [7] WARN  - HttpContext.Current.User.Identity NT AUTHORITY\SYSTEM
2015-04-23 10:47:19,681 [7] WARN  - WindowsIdentity.GetCurrent() NT AUTHORITY\SYSTEM
我了解WindowsIdentity.GetCurrent().Name返回系统用户.我不明白为什么Request.LogonUserIdentity和Request [LOGON_USER]的输出不同.我需要来自User的WindowsIdentity对象,其名称由Request [LOGON_USER]返回.
任何人都能指出我正确的方向吗?
下午好,
我目前面临一个问题,我有一个服务器名称列表,我需要验证一个Windows身份验证用户是否具有指定服务器名称的权限,而不尝试建立与指定服务器的连接,然后我提供服务器列表给他们.例如:
服务器:A,B,C,D
Joe拥有A和D的权限,但没有B和C的权限,所以Joe应该只在他的服务器列表中看到A和D.
我该如何处理这个问题?我应该从Active Directory中提取吗?我知道如何提取用户的身份,但是在哪里提取服务器信息并找出用户是否拥有权限是一个完全不同的故事.任何文档,代码示例,文章等都是有用的.
关于工作环境的注意事项
关于服务器列表的附注
此列表存储在数据库中,但我不认为这对权限方面有帮助.我已经使用以下SQL查询解决了针对各个数据库检查权限的问题:
SELECT name
FROM sys.databases
WHERE HAS_DBACCESS(name) = 1
ORDER BY name
谢谢您的帮助!
-杰米
结论
基本上,我发现没有可能的方法来查询远程服务器上的AD组而不尝试建立连接,因此找到的所有样本的执行将使用IA标记用户帐户.对于其他有类似问题且不必担心IA会对用户施加压力的问题,我在下面列出了一些解决方案,您可以尝试满足您的需求(以下所有方法在正确实施时都能正常工作).
解决方案
如果您已通过模拟或其他方式(SQL Server Auth)访问服务器,则可以使用以下内容查看该成员是否分配了任何服务器角色:
SELECT IS_SRVROLEMEMBER('public')
您还可以使用Microsoft.SqlServer.Management.Smo命名空间使用Microsoft.SqlServer.Smo程序集中提供的Login类.但是,您可能会或可能不会将Microsoft.SqlServer.SqlClrProvider命名空间从GAC移动到BIN.有关此内容的更多信息,请参阅此StackOverflow帖子,以及此 Microsoft Connect线程,其中说明了以下内容:
客户端应用程序不应使用Program Files文件夹中的程序集,除非它们来自特定的SDK文件夹(例如"C:\ Program Files(x86)\ Microsoft SQL Server\130\SDK")
您甚至可以在try catch中执行基本连接测试,以查看连接是否有效.
using (SqlConnection conn = new SqlConnection(connString)) {
     try {
          conn.Open();
          conn.Close();
     } catch …