Restricting access to push messages

  • lowecg
Posted: Mon, 04/05/2010 - 05:30

Currently, a client app can request access to a message destination but there is no provision (as far as I can tell) for a server side authorisation security policy governing whether access to a destination is actually allowed or not. I've had a poke around the code and managed to come up with an approach which overrides an existing Seam component SeamFlamingoDestinationTranslator but I wanted to run my solution by this list to get some feedback on my approach. Basically, I've replaced the usual destination translator with my own which applies an authorisation check during the destination to JMS consumer mapping process such that if a client requests a destination to which they're not allowed to access then the JMS consumer is not returned, preventing messages being received from JMS and sent back to the client.

This approach works quite well but to be honest it kind of feel like I'm hacking the Flamingo framework to add my functionality. I only took this approach because I struggled to find appropriate extension points - or was the intention for the definition of new components by overriding framework components using Seam precedence? My worry is that if extending behaviour in this way was not intended, then future versions of Flamingo may well break my code.

/**
* An extension of the standard Seam implementation which converts destinations from {@code FlamingoDestination} to JMS
* {@code Destination}. This version filters destinations based on what the current user is allowed to see.
*/
@Scope(ScopeType.APPLICATION)
@BypassInterceptors
@Name(FlamingoDestinationTranslator.NAME)
@Install(precedence = Install.DEPLOYMENT)
public class RestrictedSeamFlamingoDestinationTranslator extends FlamingoDestinationTranslator {

/**
* Create new translator
*/
public RestrictedSeamFlamingoDestinationTranslator() {
super(SeamFlamingoPushServerConfiguration.instance());
}

@Override
public Set getConsumers(List destinations, Session session) {
Validation.notNull("destinations", destinations);
Validation.notNull("session", session);

final Context sessionContext = Contexts.getSessionContext();

final MessageSecurity messageSecurity = (MessageSecurity) sessionContext.get(MessageSecurity.NAME);

if (messageSecurity == null) {
// If message security does not exist then we've not logged in yet, so
// restrict access to all messages.
return Collections.emptySet();
}
else {
final List approved = messageSecurity.filterDestinations(destinations);

return super.getConsumers(approved, session);
}
}
}

@Name(MessageSecurity.NAME)
@Scope(ScopeType.SESSION)
@BypassInterceptors
public class MessageSecurity {

public static final String NAME = "com.app.messaging.security";

private final Set allowedDestinations = new HashSet();

public void clear() {
allowedDestinations.clear();
}

public boolean addDestination(final String destination) {
return allowedDestinations.add(destination);
}

public List filterDestinations(List destinations) {
final List approved = new ArrayList(destinations.size());

for (FlamingoDestination destination : destinations) {
if (allowedDestinations.contains(destination.getName())) {
approved.add(destination);
}
else {
Logger.getLogger(MessageSecurity.class.getName()).debug("Access to destination '" + destination.getName() + "' denied.");
}
}

return approved;
}
}

Then when a user logs in, the MessageSecurity object is created and populated with allowed destinations:

public boolean login() {

...

final Context sessionContext = Contexts.getSessionContext();

MessageSecurity messageSecurity = (MessageSecurity) sessionContext.get(MessageSecurity.NAME);

if (messageSecurity == null) {
messageSecurity = new MessageSecurity();

sessionContext.set(MessageSecurity.NAME, messageSecurity);
}

messageSecurity.addDestination("serv.exadel.com");
messageSecurity.addDestination("db.exadel.com");
}

With the above code in place, a client can make requests to the server for the message prior to login and no messages are delivered. After the user logs in and permitted destinations are added to the context, messages are then delivered.

Cheers,

Chris.

Thank you for your interest

  • dkorotych
  • 04/15/10
  • Thu, 04/15/2010 - 07:50

Thank you for your interest in our work and even more so for the sample code.
I think your code does not violate our concept :). Flamingo is primarily a transport for the transfer of objects and call methods, with some additional features. We need to demonstrate it capabilities. Security this is an area which is heavily dependent on the your applications.

Ultram foreordainments

  • neilrayez
  • 07/25/11
  • Fri, 07/29/2011 - 09:29

Ultram foreordainments neomorphic Generic Klonopin coracoclavicular Highness Klonopin overdose coemployee pacesetter Ambien Dramatist organicism