【问题标题】:MessageQueue.CanWrite always returns trueMessageQueue.CanWrite 总是返回 true
【发布时间】:2013-08-06 14:35:12
【问题描述】:

我已取消选择在专用队列上发送消息的权限,但 MessageQueue.CanWrite 永远不会返回 false。我可以切换接收消息权限,CanRead 属性按预期响应。为什么CanWrite 属性的行为会有所不同?

我已经用几个不同的 AD 用户测试了这个问题,结果是一样的。

是否有不同的方法来验证特定用户帐户是否可以将消息发送到特定的远程专用队列?

public class SendBehavior : IMsmqRuleBehavior
{
    public bool Validate(string queuePath)
    {
        using (var queue = new MessageQueue(queuePath, QueueAccessMode.Send))
        {
            return queue.CanWrite;                                        
        }
    }
}

public class ReceiveBehavior : IMsmqRuleBehavior
{
    public bool Validate(string queuePath)
    {
        using (var queue = new MessageQueue(queuePath, QueueAccessMode.Receive))
        {
            return queue.CanRead;                
        }
    }
}

【问题讨论】:

  • 看来如果QueueAccessMode.Send 被请求,CanWrite 很可能是true(附带问题:您是否为此队列切换了“已验证”复选框)
  • 我考虑过,但默认的 QueueAccessMode 是 SendAndReceive,CanRead 测试的行为与预期一样,QueueAccessMode 设置为 Receive。
  • 当您设置QueueAccessMode.Receive 时,CanWrite 是否会变为false?因为从我对 ILSpy 中 MessageQueue 类的回顾来看,似乎只有您提供的模式才能反映这些属性值。
  • 另外,发送消息时会失败吗?看来这将是确定这是否是预期行为的关键。
  • 已验证复选框未选中。现在是,行为没有改变。

标签: c# c#-4.0 msmq


【解决方案1】:

据我所知,MessageQueue.CanWrite 的这种行为符合预期。如果您深入研究 MessageQueue 类的内容,您会发现它创建了一些帮助对象,这些对象通过以下方式影响该属性的值:

  1. 如果您传递QueueAccessMode.Send(或SendAndReceive),将创建一个内部访问模式助手,如果(this.accessMode & QueueAccessMode.Send) != (QueueAccessMode)0,则返回true

  2. 如果#1 是true,然后它会尝试打开队列以将其存储到缓存中,使用您请求的访问模式和共享。此时调用了原生方法MQOpenQueue,它的注释中有以下内容(强调我的):

    如果调用的应用程序不允许在请求的模式下打开队列的访问权限,可能会发生以下两种情况:

    • 如果dwAccess设置为MQ_SEND_ACCESSMQOpenQueue会成功,但是当应用程序尝试发送消息时会返回错误。
    • 如果dwAccess 设置为MQ_PEEK_ACCESSMQ_RECEIVE_ACCESSMQOpenQueue 将失败并返回MQ_ERROR_ACCESS_DENIED (0xC00E0025)。在这种情况下,队列句柄不会返回给phQueue

因此,给定具有有效队列名称和共享模式的QueueAccessMode.Send(或SendAndReceive),我的理解是CanWrite 将返回true,即使您确实无权发送消息。

基本上,您似乎只会收到CanWrite == false,当且仅当:

  1. 您传递的QueueAccessMode 不是SendSendAndReceive

【讨论】:

  • 感谢您深入研究。为什么切换队列上的接收消息权限会导致“CanRead”属性的真/假切换,当我将消息发送到队列时,禁用发送时,消息永远不会进入队列,但我不是也收到异常。这对我来说似乎很奇怪。我认为 CanRead 和 CanWrite 的行为方式相同。
  • @ChadLazette:我希望我能给你一个更好的答案,但据我所知,这种行为并不是基于另一端队列的真实权限。
  • 很公平。我很感激。我必须想出另一种方法来验证用户是否可以发送消息。
猜你喜欢
  • 2017-05-10
  • 2013-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多