从远程计算机读取队列中的消息

时间:2015-10-09 08:04:52

标签: c# msmq user-accounts

我们正在尝试在我们的应用程序中实现MSMQ,并且我们面临下一个问题:我们的应用程序(控制台应用程序)在域X中的本地计算机(machine1)用户帐户下启动。

在同一个域上有另一台机器(machine2),在这台机器上是队列​​。在域X上有一个具有管理员权限的用户帐户,该用户可以完全控制队列,但是当我们的应用程序启动时,因为它在本地帐户下运行,所以它没有权限读取消息。 / p>

是否有任何解决方案如何仅从代码中解决此问题?我们无法更改我们的控制台应用程序正在使用的用户帐户。我想将模仿作为最后的解决方案。

你有解决这个问题的方法吗?

3 个答案:

答案 0 :(得分:0)

私人和公共队列都应该允许您这样做:https://technet.microsoft.com/en-us/library/cc772532.aspx

查看公共和专用队列下的部分。

公共队列应该可用于任何域帐户,包括计算机帐户。

私人队列允许任何人写作,但需要特别许可才能阅读。

答案 1 :(得分: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();

答案 2 :(得分:0)

如果您无法模拟有效的域帐户,则必须在队列中分配“匿名登录”特殊帐户权限。 “所有人”特殊群组不起作用,因为它只涵盖域名识别的帐户。您机器的本地帐户对于域名来说是陌生的,不包括在内。