【问题标题】:Access denied when using Net.Tcp Port Sharing Service使用 Net.Tcp 端口共享服务时访问被拒绝
【发布时间】:2014-02-13 08:28:24
【问题描述】:

这个问题与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 和运行进程的帐户之间的链接不知何故没有建立。但为什么呢?

编辑:

我已经仔细检查了我正在编辑的配置是否已被服务使用。我已经尝试显式添加系统帐户和所有人,但它仍然给我一个拒绝访问错误。就好像它根本不看那个配置一样。

如何找到丢失的权限在哪里?

编辑:

我在机器上重新安装了 .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。使用端口共享没有问题,因为它是在系统帐户下运行的。

端口共享服务本身是开启的,我已经提到我已经重启了好几次机器了。

“应用服务器”角色没有安装,但是当我去添加它的时候,TCP端口共享角色已经被勾选并显示为灰色,所以肯定是安装了别的东西。 .NET 4.5.1 自带吗?

【问题讨论】:

  • 请注意,配置文件附带一个示例<system.serviceModel.activation> 部分已注释掉。在记事本中编辑它,你可能会错过它。确保在该文件中查找<!---->
  • 确实配置看起来不错。您是否尝试过不绑定到 localhost 而是绑定机器名称?

标签: c# winapi process account net.tcp


【解决方案1】:

前言:请一题一帖……

PortSharing:您在哪里启用了端口共享?我们在您的配置文件中看不到这一点。有关更多信息,请参阅:如何:Configure a Windows Communication Foundation Service to Use Port Sharing

您是否在您的服务器上安装了“应用程序服务器”角色?另见: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>

【讨论】:

【解决方案2】:

事实证明,登录类型导致权限无法与端口共享服务一起正常工作。我将其更改为 LogonType.Batch 并开始工作。

完整代码:

ProcessHelperhttp://pastie.org/private/dlkytj8rbigs8ixwtg

TokenImpersonationContexthttp://pastie.org/private/nu3pvpghoea6pwwlvjuq

【讨论】:

    【解决方案3】:

    (只是另一个可能对某人有所帮助的答案)

    事实证明,在我的情况下,登录用户没有 管理 权限。 将帐户类型更改为管理员解决了该问题。 我也没有更改SmSvcHost.exe.config中的任何内容

    【讨论】:

      猜你喜欢
      • 2016-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-10
      • 1970-01-01
      相关资源
      最近更新 更多