【问题标题】:Read messages from queue from remote computer从远程计算机的队列中读取消息
【发布时间】:2015-10-09 22:46:36
【问题描述】:

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

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

是否有任何解决方案仅通过代码解决此问题?我们无法更改控制台应用程序正在使用的用户帐户。我正在考虑使用模拟作为最后的解决方案。

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

【问题讨论】:

    标签: c# msmq user-accounts


    【解决方案1】:

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

    查看公共和私人队列下的部分。

    任何域帐户(包括计算机帐户)都应该可以使用公共队列。

    私有队列允许任何人写入,但需要特定权限才能读取。

    【讨论】:

    • 嗨,Ben,我已经阅读了这篇文章,这里声明我应该向我的用户授予“接收消息”权限。但问题是我的用户不是域用户,它是本地用户和来自 machine1 的用户,并且在 machine2 上不可见将此用户添加到队列的安全选项卡。
    【解决方案2】:

    我只能通过模拟阅读邮件。这是我的代码:

    模拟上下文包装器:

     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();
    

    【讨论】:

      【解决方案3】:

      如果您无法模拟有效的域帐户,则必须在队列上分配“匿名登录”特殊帐户权限。 'everyone' 特殊组将不起作用,因为它仅涵盖域识别的帐户。您计算机的本地帐户与域无关,不包括在内。

      【讨论】:

      • 嗨,John,由于安全问题,我们不能选择“匿名登录”,因此安全团队创建了一个仅在队列中拥有权限的域用户,并且我们使用模拟来读取消息。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-01-19
      • 1970-01-01
      • 2021-03-11
      • 1970-01-01
      • 2012-12-01
      • 2012-11-16
      • 2013-10-22
      相关资源
      最近更新 更多