2014-02-13 190 views
1

此問題與Starting processes under specific credentials from a Windows service有關,但這是一個不同的問題。使用Net.Tcp端口共享服務時訪問被拒絕

我已經從系統會話(0)中的Windows服務啓動了特定憑據下的進程,但無法偵聽端口共享URL。它在Windows Server 2008計算機上使用「工作者」域帳戶。

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和進程所運行的帳戶之間的鏈接不知道怎麼做。但爲什麼?

編輯:

我反覆檢查我的編輯的配置所使用的服務。我已經嘗試添加系統帳戶和每個人明確,但它仍然給我一個訪問被拒絕的錯誤。這就像它根本沒有在看那個配置。

如何找到缺少的權限?

編輯:

我重新安裝了機器,所有的Windows更新,仍然沒有運氣上.NET 4.5.1。

編輯:

這是複製的用戶令牌允許它使用的端口共享的正確方法?具體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?

+0

請注意,配置文件帶有一個樣本''部分註釋掉。在記事本中編輯它,你可能會錯過。一定要查找該文件中的<! - '和' - >'。 – Menahem

+1

我的配置是正確的:http://pastie.org/private/jxed8bdft0eir5uc371pq – Edgar

+0

確實配置看起來不錯。你有沒有嘗試綁定到'localhost',但機器名? – Menahem

回答

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> 

+0

我用一些答案編輯了這個問題。 – Edgar

+0

綜合頁面也是:http://blogs.msdn.com/b/andreal/archive/2009/04/05/net-tcp-ip-port-sharing.aspx和http://msdn.microsoft.com /en-us/library/aa702669.aspx –

+0

@Edgar:將您的特定帳戶添加到SmSvcHost.exe.config文件!看到編輯的答案! –

0

(只是另一個答案,可以幫助某人)

原來,在我的情況,記錄在用戶沒有行政特權。 將帳戶類型更改爲管理員解決了該問題。 我也沒有改變任何東西SmSvcHost.exe.config