我已取消选择私有队列上的发送消息的权限,但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;
}
}
}
答案 0 :(得分:3)
据我所知,MessageQueue.CanWrite
的行为按预期。如果你深入研究MessageQueue类的内容,你会发现它创建了一些帮助对象,它们以下列方式影响这个属性的值:
如果您传递QueueAccessMode.Send
(或SendAndReceive
),则会创建一个内部访问模式助手,如果true
,则返回(this.accessMode & QueueAccessMode.Send) != (QueueAccessMode)0
。
如果#1为true
,则会尝试使用访问模式和您请求的共享打开队列以将其存储到缓存中。此时,调用本机方法MQOpenQueue
,其注释中有以下内容(强调我的):
如果调用应用程序不允许以所请求的模式打开队列的访问权限,则可能发生以下两种情况:
- 如果
dwAccess
设置为MQ_SEND_ACCESS
,MQOpenQueue
将成功,但在应用程序尝试发送邮件时将返回错误。- 如果
dwAccess
设置为MQ_PEEK_ACCESS
或MQ_RECEIVE_ACCESS
,则MQOpenQueue
将失败并返回MQ_ERROR_ACCESS_DENIED
(0xC00E0025)。在这种情况下,队列句柄不会返回phQueue
。
因此,如果QueueAccessMode.Send
(或SendAndReceive
)具有有效的队列名称和共享模式,我的理解是CanWrite
将返回true
,即使您真的没有权限发送消息。
基本上,当且仅当:
时,您才会收到CanWrite == false
QueueAccessMode
不是Send
或SendAndReceive
。