I have a PR up for adding a plugin API and a plugin to support message level authentication but there are some assumptions and API changes that would be better explained and discussed here.
The premise for this change is that address level permissions while suitable for a majority of use cases are not suitable for cases where message permissions are more dynamic and or coordination with consumers to subscribe on different topics can't happen before hand. First issue that prevents this feature is that it needs access to a cached instance of authenticated users and roles in order to make message policy decisions. Instead of re-authenticate it made sense to reuse already authenticated users from the SecurityStore but it does not expose an API to retrieve the Subject or RolePrinciples. Therefore, I propose adding Subject SecurityStore#getSessionSubject(SecurityAuth session). In leu of changing the SecurityStore API it is entirely possible for plugins to use session information to reauthenticate using the ActiveMQSecurityManager5 API and then cache the Roles themselves, but this seems too burdensome. The second issue I found is that none of the existing APIs can affect delivery of a message. ActiveMQServerMessagePlugin#beforeDelivery is close since it has all the needed information, but it happens after the handle decision and can't affect delivery without the negative side effect of making it not deliverable to other consumers. The ActiveMQSecurityManager API would also make sense but it doesn't have access to the SecurityStore and the ServerConsumer is already calling out to ActiveMQServerPlugin API so extending that makes more sense. Therefore, I propose modifying the ActiveMQServerPlugin specifically extending ActiveMQServerMessagePlugin to add a boolean canAccept(ServerConsumer consumer, MessageReference reference). However, the drawback to this is that Artemis allows multiple plugins all of which could implement canAccept. This means the results of multiple plugin#canAccept need to be taken into account by either requiring ALL(logical AND) or ANY(logical OR) canAccept to be true before delivering a message to a consumer. Both are acceptable but ANY makes it hard to have a default implantation of canAccept because a true would override any other false and false would filter all messages if a plugin doesn't care about implementing canAccept. So, I am proposing that the results of ALL plugin#canAccepts be true before the ServerConsumer delivers a message to a consumer. Hopefully this gives more context to my PR and can help reviewers. Ryan Yeats [Octo | Emerging Technology. Human Impact.]<https://www.octoconsulting.com/>
