views:

998

answers:

2

I'm working on an application that allows users to send internal message to one-another.

I'll tell you what the current setup is and please help me figure out how to make it work or perhaps suggest another angle to take. We're using BlazeDS with Spring.

  • User A listens for messages on message topic Chat.A
  • User B listens for messages on message topic Chat.B
  • Both users listen for global messages (system-wide messages) on topic Chat.System

So we have a multi-topic consumer for the personal message topic and one for the global message topic.

So a couple of questions I have:

  1. Is it better to do it as two distinct consumers (that share the same handler function) or as one, multi-topic consumer?
  2. How do I check that the client A is actually the one listening to Chat.A and not just some one else that knows how to write BlazeDS clients? We have Spring Security in place, but how can I listen for subscription requests and block them if their user name (pulled from security context) doesn't match the sub-topic that they requested?

I've also read about selectors. Well, that looked promising, but again, how do I check that when a consumer uses selector="for == A || for == System that the consumer belongs to a client that has authenticated as that "for" user.

  1. How do selectors compare/contrast to sub-topics? What's the best situation for each of them?
+1  A: 

A selector is basically an expression you can use to filter which messages will be dispatched through your consumer. According to the docs, it uses SQL 92 conditional expression syntax:

http://livedocs.adobe.com/blazeds/1/blazeds%5Fdevguide/help.html?content=messaging%5F6.html

A subtopic is sort of a special case of a selector, filtering out messages whose "DSSubtopic" header don't match the provided value.

The important thing to understand with both of these is that the client determines which messages are sent to it, and as such it cannot be relied upon entirely for security.

To implement secure server-based filtering of messages based on an authenticated user's identity, see my answer to a related question here:

http://stackoverflow.com/questions/916437/flex-messaging-security/917189#917189

As far as multiple Consumers vs. MultiTopicConsumer, not sure there. They're both going to use the same underlying ChannelSet, so it ought not to have a big performance difference. I think it's mostly a question of whether it's convenient to have one event handler that responds to all messages from the MultiTopicConsumer or whether it's easier to have separate event handlers for each Consumer.

cliff.meyers
Thank you for that answer. Is there a way to intercept a subscription request with an adapter or something, and at that point, we disallow access to a topic that they've requested if it doesn't match their user name?
davidemm
A: 

I usually use subtopics for this. But if you do it that way make sure that you disable subscriptions to wildcard subtopics.

James Ward
Thanks so much! I used your example to do what I needed. I was trying to examine subscription requests by looking at Object manage(CommandMessage commandMessage) (http://livedocs.adobe.com/livecycle/8.2/programLC/programmer/javadoc/flex/messaging/services/messaging/adapters/MessagingAdapter.html). I moved my security logic to the allowSubscribe(Subtopic subtopic) method and it worked like a charm!
davidemm
Via Spring-Flex integration I used: <flex:message-destination id="my-messages" allow-subtopics="true" subtopic-separator="." service-adapter="MyMessagingAdapter"/> where "MyMessagingAdapter" is a reference to a bean. In the bean (adapter), I examine the subtopic and I make sure that there are no wildcards AND the lowest sub-topic matches the username pulled from the security context: SecurityContextHolder.getContext().getAuthentication().getName())
davidemm