I have an RMI server which uses JAAS as authentication mechanism and exposes several business objects (MBeans). The JAAS login module contains multiple credentials each associated with different permissions, e.g. READ-ONLY, READ-WRITE, DEV etc. MBeans in turn are to rely on those permissions in order to allow/reject certain method calls.
I have spent a good few days researching/experimenting and so far could not find a mechanism which would allow MBeans to determine the authenticated RMI user when a call is invoked on them.
First of all I am aware that there is RemoteServer::getClientHost()
, but identifying a client by IP is not suitable since multiple processes could potentially connect from a single IP.
So far, my findings are:
- When an RMI connection is established the user is authenticated and a new
RMIConnectionImpl
instance is created RMIConnectionImpl
contains authentication subject/principals as well as what looks like a unique connection id- None of the identifying information of
RMIConnectionImpl
is available/retrievable when remote calls are made
Since it seems to be impossible to figure out which RMIConnectionImpl
the call is coming from I have initially tried to use the thread which was attempting JAAS authentication as identifier. That plan didn't work since, naturally, RMI uses thread pools and subsequent remote method invocations were not guaranteed to be carried out by the same thread.
Another idea I contemplated was to use AspectJ LTW to intercept RMIConnectionImpl::invoke(..)
and to associate a user with a thread through some global ThreadLocal
. But there is a world of pain to get it all working, plus it does feel like a massive overkill.
Surely there must be a simpler solution to this really common use case. Hence I am quite puzzled and worried I might be missing something big here.
Any help/suggestions would be much appreciated.