这个问题与Starting processes under specific credentials from a Windows service有关,但这是一个不同的问题。
我已在特定凭据下从系统会话(0)中的Windows服务启动了一个进程,但它无法侦听端口共享URL。它在Windows Server 2008计算机上使用“Worker”域帐户。
我的 SMSvcHost.exe.config 文件:http://pastie.org/private/jxed8bdft0eir5uc371pq
我已经重新启动了服务和机器,但它仍然给了我这个例外:
System.ServiceModel.CommunicationException: The service endpoint failed to listen on the URI 'net.tcp://localhost:5400/Agent/384' because access was denied. Verify that the current user is granted access in the appropriate allowAccounts section of SMSvcHost.exe.config. ---> System.ComponentModel.Win32Exception: Access is denied
at System.ServiceModel.Activation.SharedMemory.Read(String name, String& content)
at System.ServiceModel.Channels.SharedConnectionListener.SharedListenerProxy.ReadEndpoint(String sharedMemoryName, String& listenerEndpoint)
启动流程的 ProcessHelper 代码:http://pastie.org/private/iytqehsdfujrgil1decda。我正在调用StartAsUserFromService
方法。
我认为配置中的SID与进程正在运行的帐户之间的链接是以某种方式进行的。但为什么呢?
编辑:
我已经仔细检查了我正在编辑的配置是否被该服务使用。我已经尝试明确添加系统帐户和Everyone,但它仍然给我一个访问被拒绝错误。这就像它根本没有看那个配置。
如何找到遗失权限的位置?
编辑:
我在机器上重新安装了.NET 4.5.1并且所有Windows更新仍然没有运气。
编辑:
这是复制用户令牌以允许其使用端口共享的正确方法吗?特别是SecurityDescriptor
位?
private static ImpersonationResult ImpersonateUser(string domain, string username, string password)
{
IntPtr token = IntPtr.Zero;
IntPtr primaryToken = IntPtr.Zero;
try
{
// Get token
bool bImpersonated = LogonUser(
username,
domain,
password,
(int)LogonType.NetworkClearText,
(int)LogonProvider.Default,
ref token);
if (!bImpersonated)
{
throw new Exception(string.Format("Failed to impersonate identity. Error code: {0}", Marshal.GetLastWin32Error()));
}
SecurityDescriptor sd = new SecurityDescriptor();
IntPtr ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(sd));
Marshal.StructureToPtr(sd, ptr, false);
InitializeSecurityDescriptor(ptr, 1);
sd = (SecurityDescriptor)Marshal.PtrToStructure(ptr, typeof(SecurityDescriptor));
// Set up security
bool bDecriptorSet = SetSecurityDescriptorDacl(
ref sd,
true,
IntPtr.Zero,
false);
if (!bDecriptorSet)
{
throw new Exception(string.Format("Failed to set security descriptor. Error code: {0}", Marshal.GetLastWin32Error()));
}
SecurityAttributes processAttributes = new SecurityAttributes();
processAttributes.lpSecurityDescriptor = ptr;
processAttributes.nLength = (uint)Marshal.SizeOf(sd);
processAttributes.bInheritHandle = true;
// Duplicate token
bool bTokenDuplicated = DuplicateTokenEx(
token,
0,
ref processAttributes,
(int)SecurityImpersonationLevel.SecurityImpersonation,
(int)TokenType.TokenPrimary,
ref primaryToken);
if (!bTokenDuplicated)
{
throw new Exception(string.Format("Failed to duplicate identity token. Error code: {0}", Marshal.GetLastWin32Error()));
}
SecurityAttributes threadAttributes = new SecurityAttributes();
threadAttributes.lpSecurityDescriptor = IntPtr.Zero;
threadAttributes.nLength = 0;
threadAttributes.bInheritHandle = false;
// Got the token
return new ImpersonationResult()
{
Token = primaryToken,
ProcessAttributes = processAttributes,
ThreadAttributes = threadAttributes
};
}
finally
{
FreeToken(token);
}
}
private static void FreeToken(IntPtr token)
{
if (token != IntPtr.Zero)
{
CloseHandle(token);
}
}
编辑:
以下是我的进程的app.config位,它启用了端口共享:http://pastie.org/private/8ekqeps4d7rmo7hnktsw
这是启动流程的服务的app.config位:http://pastie.org/private/nqqcwz8bvjb5fzp48yavbw。使用端口共享没有问题,因为它在系统帐户下运行。
端口共享服务本身已启用,我已经提到我已多次重启机器。
未安装“Application Server”角色,但是当我添加它时,TCP端口共享角色已经勾选并显示为灰色,因此必须安装其他东西。它是否附带.NET 4.5.1?
答案 0 :(得分:1)
前言:请用一个问题一个线程......
PortSharing:您在哪里启用了端口共享?我们在您的配置文件中看不到这一点。有关更多信息,请参阅:如何:Configure a Windows Communication Foundation Service to Use Port Sharing
您是否在服务器上安装了“Application Server”角色?另见:Checklist: Use TCP Port Sharing to Allow Multiple WCF Applications to Use the Same TCP Port
系统上是否启用了端口共享?请参阅:How to: Enable the Net.TCP Port Sharing Service
另外,你重启了服务器吗?有时这是必需的(或至少所有使用此端口的服务),请参阅:http://blogs.msdn.com/b/joncole/archive/2010/06/10/tcp-port-sharing-access-is-denied.aspx
有关端口共享的全面说明是:http://blogs.msdn.com/b/andreal/archive/2009/04/05/net-tcp-ip-port-sharing.aspx
另请注意,如果需要,您必须添加一些帐户以进行激活: Configuring the Net.TCP Port Sharing Service
您确定 SmSvcHost.exe.config 允许从您的帐户进行访问,您的进程是否正在运行?
<configuration>
<system.serviceModel.activation>
<net.tcp listenBacklog="16" <!—16 * # of processors -->
maxPendingAccepts="4"<!— 4 * # of processors -->
maxPendingConnections="100"
receiveTimeout="00:00:30" <!—30 seconds -->
teredoEnabled="false">
<allowAccounts>
<!-- LocalSystem account -->
<add securityIdentifier="S-1-5-18"/>
<!-- LocalService account -->
<add securityIdentifier="S-1-5-19"/>
<!-- Administrators account -->
<add securityIdentifier="S-1-5-20"/>
<!-- Network Service account -->
<add securityIdentifier="S-1-5-32-544" />
<!-- IIS_IUSRS account (Vista only) -->
<add securityIdentifier="S-1-5-32-568"/>
</allowAccounts>
</net.tcp>
</system.serviceModel.activation>
答案 1 :(得分:1)
事实证明,登录类型导致权限无法与端口共享服务一起正常运行。我将其更改为LogonType.Batch
并开始工作。
完整代码:
ProcessHelper :http://pastie.org/private/dlkytj8rbigs8ixwtg
TokenImpersonationContext :http://pastie.org/private/nu3pvpghoea6pwwlvjuq
答案 2 :(得分:0)
(只是另一个可能对某人有帮助的答案)
事实证明,在我的情况下,登录用户没有管理权限。
将帐户类型更改为管理员解决了问题。
我也没有改变SmSvcHost.exe.config