2015-10-09 87 views
0

我們試圖在我們的應用程序中實現MSMQ,並面臨下一個問題:我們的應用程序(控制檯應用程序)在域X中的本地計算機(machine1)用戶帳戶下啓動。從遠程計算機讀隊列

在同一個域上有另一臺機器(machine2),在這臺機器上是隊列​​。在域X上有一個具有管理權限的用戶帳戶,並且該用戶對隊列有完全控制權,但是當我們的應用程序啓動時,由於它在本地帳戶下運行,所以它沒有閱讀messagess的權限。

有沒有解決方案只能從代碼解決這個問題?我們無法更改我們的控制檯應用程序正在使用的用戶帳戶。我正在考慮使用模擬作爲最後的解決方案。

你有解決這個問題的辦法嗎?

回答

0

私人和公共隊列應該讓你做到這一點:https://technet.microsoft.com/en-us/library/cc772532.aspx

看一看公共及私人隊列下的部分。

公共隊列應該可用於任何域帳戶,包括機器帳戶。

私人隊列允許任何人寫,但需要特定的權限閱讀。

+0

嗨本,我讀過這篇文章,並在這裏指出,我應該給予我的用戶權限「接收消息」。但問題是我的用戶不是域用戶,它是本地用戶,並且來自machine1的此用戶,並且它在machine2上不可見,因此無法將此用戶添加到隊列的安全選項卡。 –

0

我只能通過模擬來閱讀郵件。這裏是我的代碼:

冒充上下文包裝:

public class WrapperImpersonationContext 
    { 
     [DllImport("advapi32.dll", SetLastError = true)] 
     public static extern bool LogonUser(String lpszUsername, String lpszDomain, 
     String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken); 

     [DllImport("kernel32.dll", CharSet = CharSet.Auto)] 
     public extern static bool CloseHandle(IntPtr handle); 

     private const int LOGON32_PROVIDER_DEFAULT = 0; 
     private const int LOGON32_LOGON_INTERACTIVE = 2; 

     private string m_Domain; 
     private string m_Password; 
     private string m_Username; 
     private IntPtr m_Token; 

     private WindowsImpersonationContext m_Context = null; 


     protected bool IsInContext 
     { 
      get { return m_Context != null; } 
     } 

     public WrapperImpersonationContext(string domain, string username, string password) 
     { 
      m_Domain = domain; 
      m_Username = username; 
      m_Password = password; 
     } 

     [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")] 
     public void Enter(out string result) 
     { 
      if (this.IsInContext) 
      { 
       result = "not in context"; 
       return; 
      } 
      m_Token = new IntPtr(0); 
      try 
      { 
       m_Token = IntPtr.Zero; 
       bool logonSuccessfull = LogonUser(
        m_Username, 
        m_Domain, 
        m_Password, 
        LOGON32_LOGON_INTERACTIVE, 
        LOGON32_PROVIDER_DEFAULT, 
        ref m_Token); 
       if (logonSuccessfull == false) 
       { 
        result = "logon failed"; 
        int error = Marshal.GetLastWin32Error(); 
        throw new Win32Exception(error); 
       } 
       else 
       { 
        result = "logon succseeded"; 
       } 
       WindowsIdentity identity = new WindowsIdentity(m_Token); 
       m_Context = identity.Impersonate(); 
      } 
      catch (Exception exception) 
      { 
       result = "exception: " + exception.Message; 
       // Catch exceptions here 
      } 
     } 


     [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")] 
     public void Leave() 
     { 
      if (this.IsInContext == false) return; 
      m_Context.Undo(); 

      if (m_Token != IntPtr.Zero) CloseHandle(m_Token); 
      m_Context = null; 
     } 
    } 

閱讀郵件:

MessageQueue queue = new MessageQueue(@"FormatName:DIRECT=OS:servername\PRIVATE$\queue_name"); 
WrapperImpersonationContext context = new WrapperImpersonationContext("domain", "username", "password"); 
context.Enter(out result); 
Message msg = queue.Receive(); 
context.Leave(); 
0

如果你無法模擬有效的域帳戶,你就必須分配「匿名登錄'在隊列上的特殊帳戶權限。 「所有人」特別小組將不會工作,因爲它只涵蓋該域所承認的帳戶。您的計算機本地帳戶對於域而言是外來的,不包括在內。

+0

嗨John,由於安全問題,我們不能選擇「匿名登錄」,因此安全團隊創建了一個僅在隊列中擁有權限的域用戶,並且我們使用模擬來讀取消息。 –