2015-10-09 86 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,由于安全问题,我们不能选择“匿名登录”,因此安全团队创建了一个仅在队列中拥有权限的域用户,并且我们使用模拟来读取消息。 –