使用C#以指定的用户名和密码启动进程时,抛出“访问被拒绝”异常。

9

在一个运行身份模拟的.NET 3.5 Web应用程序中,我正在尝试通过以下方式执行进程:

var process = new Process 
             { StartInfo = 
                    { CreateNoWindow = true, 
                      FileName = "someFileName", 
                      Domain = "someDomain", 
                      Username = "someUserName", 
                      Password = securePassword, 
                      UseShellExecute = false
                    }
             };

process.Start();

-在web.config中将信任模式更改为完全并没有解决问题。

-请注意,变量securePassword是先前在代码中设置的secureString。

这会抛出一个异常,其消息为'拒绝访问'。如果我删除用户名和密码信息,则异常消失,但进程以aspnet_wp身份启动,而不是我需要的用户身份。

我在多个论坛中看到了这个问题,但从未看到提供解决方案。有什么想法吗?


有没有一个关于这个的完整源代码示例的最终解决方案? - Kiquenet
6个回答

2
您可以使用ProcessStartInfo来指定凭据。关键在于密码是一个安全字符串,因此您必须将其作为字节数组传递。
代码可能如下所示:
Dim startInfo As New ProcessStartInfo(programName)
        With startInfo
            .Domain = "test.local"
            .WorkingDirectory = My.Application.Info.DirectoryPath
            .UserName = "testuser"
            Dim pwd As New Security.SecureString
            For Each c As Char In "password"
                pwd.AppendChar(c)
            Next
            .Password = pwd

            'If you provide a value for the Password property, the UseShellExecute property must be false, or an InvalidOperationException will be thrown when the Process..::.Start(ProcessStartInfo) method is called. 
            .UseShellExecute = False

            .WindowStyle = ProcessWindowStyle.Hidden
        End With

假设该进程是VB6应用程序的exe文件。在项目加载时,我需要修改VB6应用程序吗?还是要在VB6中创建一些全局参数来捕获从该程序发送的用户名或密码,并检查这些参数是否存在,然后执行VB6应用程序的登录屏幕的登录按钮单击操作。 - Teju MB
1
@TejuMB 在原始问题和我的答案中,ProcessStartInfo 仅用于作为不同的 Windows 用户启动进程(可能是因为权限不同)。ProcessStartInfo 上有一个 Arguments 属性 [链接]http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.arguments(v=vs.110).aspx,因此您也可以发送参数以供您修改 VB6 应用程序接收,但这超出了本问题的范围。 - Mike L

1

不确定这是否与您的问题相关,但我曾遇到过类似的问题,答案是该账户在机器上没有扮演角色的权限。您可以通过在机器上使用本地策略管理器将该帐户添加到“身份验证后模拟客户端”策略中来更改这种情况。


如何将帐户添加到“身份验证后模拟客户端”策略中? - Teju MB
在管理工具中,您会找到“本地安全策略”,运行它并选择“用户权限分配”。在列表中找到“身份验证后模拟客户端”,双击它。然后,您只需要添加用户或用户所属的组即可。您可以在此处阅读更多信息http://technet.microsoft.com/en-us/library/dn221967.aspx,了解分配此权限的含义。 - Brian ONeil

1
我采用了不同的方法,将整个应用程序放在自己的应用程序池中,以最初模拟的用户身份运行。现在,当asp.net生成一个新进程时,它会在用户的上下文中生成,而不是aspnet_wp。虽然这不是我发布的问题的确切解决方案,但对我们的情况起作用。

0

我在一个项目中遇到了与你相同的问题。理论上应该有一种方法可以使用给定的凭据从 Web 应用程序中生成进程,但实际上,这只是一个临时的解决方案。最终我做的是让应用程序将信息推送到 MSMQ 中,并有一个 Windows 服务弹出队列项并处理请求。

即使您的应用程序正在模拟用户,它仍然希望在 aspnet 用户帐户下运行。


0

检查代码访问安全级别,因为进程需要完全信任。您的Web应用程序可能在部分信任设置下运行。

来自Process MSDN页面:

权限

* LinkDemand
对于立即调用者的完全信任。此类不能被部分受信任的代码使用。

* InheritanceDemand
对于继承者的完全信任。此类不能被部分受信任的代码继承。


0

我想提一下,我已经尝试了这个网站上的代码,包括评论中提到的更新代码。这段代码以模拟身份运行进程(这就是我所需要的),但标准错误重定向失败了——因此,对于那些不关心处理stderr的人来说,这个链接可能很有用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接