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.
Related
Consider this scenario: I have N>2 software components (microservices) that can communicate through two different communication protocols depending on how they are deployed. In other words, I have two deployment scenarios:
The components are to be deployed on the same machine. In this case I don't know if it makes sense to use HTTP to communicate these two components, if I think about performance. I understand that there are more efficient ways to communicate two processes on the same machine using java, such as sockets, RMI, RPC ...
The components are to be deployed on N different machines. In this case, it seems to me that it makes sense for me to use HTTP to communicate these components.
In short, what I want to do is to be able to configure the communication protocol depending on the way I perform the deployment: On a single machine, for example, use RMI, but when I deploy on two machines, use HTTP.
Does anyone know how I can do this using Spring Boot?
Many Thanks!
Fundamental building block of protocols like RMI or HTTP is socket communication. If you are not looking for the comfort of HTTP or RMI, and priority is performance, pure socket communication is your choice.
This will raise other concerns like, deployment difficulties. You should know IP address of both nodes in advance.
Another option, is to go for unix -domain socket for within server communication. For that you have to depend on JunixSocket.
If you want to go another route, check all inter process communication options.
EDIT
As you said in comment "It is simply no longer a question of two components but of many". In that scenario, each component should be a micro-service And should be capable to interact with each other. If that is the choice most scalable protocol are REST/RPC both are using HTTP protocol under the hood. REST is ideal solution for an API to be developed against a data source using CRUD operations. RPC is more lean towards action oriented API. You can find more details to identify the difference in between REST and RPC here.
How I understand this is...
if the components (producer and consumer) are deployed on the same host then use an optimized protocol and if on different hosts then use HTTP(s)
Firstly, there must be a serious driver to go down this route. I take it the driver here is performance. You would like to offer faster performance on local deployment and compartively compromised speeds on distributed deployments. BTW, given that we are in a distributed deployment world (or atleast where we are headed) HTTP will be what will survive. Custom protocols are discouraged.
Anyways... I would say your producer application should be in a self healing / discovery mode. On start-up (or periodically) it could check the health of the "optimized" end-point and decide whether it the optimized receiver is around. The receiver would need to stand behind a load-balancer. If the receiver is not up then go towards HTTP(S) and setup this instance accordingly at runtime.
For the consumer, it would need to keep both the gates (HTTP and optimized) open. It should be ready to handle requests from either channel.
In SpringBoot you can have a healthCheck implmented and switch the emitter on/off depending on the health of optimized end-point. If both end-points are unhealthy then surely the producer cannot emit anything. Apart from this the rest is just normal dependency-injection.
I'm starting to develop what should become a client-server Application using Hibernate, Spring and Eclipse RCP (for the client). This is the first time I'm designing an application from the beginning so I'm just making my first steps.
I have set up Spring on both client and server using RMI for remoting (but I wouldn't mind using something else if there was a clear advantage). So right now I'm able to call exposed services of the server from different clients to get information from the database. What I haven't done is get any kind of authentication in place, so basically the server just answers to the different clients without knowing anything about them, there is not concept of a session yet. Of course this has to change since I need different user to have different roll and so on, but right now the problem I'm facing is getting the server to notify the client when certain thing happen.
My idea to solve this problem was to have a queue of events at the Server and have the clients get them every 3 second or so. The server would then identify the client by it's session token and send the appropriate events. Yet my partner in this project is concerned that this technique (polling) might waste too much bandwidth unnecessarily.
So to bring it to the point. What are the standard techniques for a server to notify a client about changes using Spring? Please notice that I'm not developing a web application and that this is only intended to be used withing a private network. That is one of the difficulties I've been facing: every single tutorial about Spring security or remoting assumes you are making a web application, but I really don't want to get lost into the details of Spring MVC and web applications in general.
Any resources would be appreciated. A good and long tutorial on the matter would be great.
EDIT: Hmm, it looks like JMS might be what I'm looking for.
As I understand, the issues you are facing is identifying a client in request and correlate different client request i.e. have something like a session.
Spring also support RMI over HTTP protocol (Using Hessian and its own HTTP Invokers). Check out this link (Section 17.3). Now once you have transport as HTTP, it has inherent Basic Authentication and session which can be leveraged to get around the issues you are facing.
This is just a pointer. I would be curious to know how eventually you resolved your problem.
I am studing java for web and it mentions http is stateless.
what does that mean and how it effects the programming
I was also studying the spring framework and there it mentions some beans have to declared as inner beans as their state changes . What does that means?
HTTP -- that is the actual transport protocol between the server and the client -- is "stateless" because it remembers nothing between invocations. EVERY resource that is accessed via HTTP is a single request with no threaded connection between them. If you load a web page with an HTML file that within it contains three <img> tags hitting the same server, there will be four TCP connections negotiated and opened, four data transfers, four connections closed. There is simply no state kept at the server at the protocol level that will have the server know anything about you as you come in.
(Well, that's true for HTTP up to 1.0 at any rate. HTTP 1.1 adds persistent connection mechanisms of various sorts because of the inevitable performance problems that a truly stateless protocol engenders. We'll overlook this for the moment because they don't really make HTTP stateful, they just make it dirty-stateless instead of pure-stateless.)
To help you understand the difference, imagine that a protocol like Telnet or SSH were stateless. If you wanted to get a directory listing of a remote file, you would have to, as one atomic operation, connect, sign in, change to the directory and issue the ls command. When the ls command finished displaying the directory contents, the connection would close. If you then wanted to display the contents of a specific file you would have to again connect, sign in, change to the directory and now issue the cat command. When the command displaying the file finished, the connection would again close.
When you look at it that way, though the lens of Telnet/SSH, that sounds pretty stupid, doesn't it? Well, in some ways it is and in some ways it isn't. When a protocol is stateless, the server can do some pretty good optimizations and the data can be spread around easily. Servers using stateless protocols can scale very effectively, so while the actual individual data transfers can be very slow (opening and closing TCP connections is NOT cheap!) an overall system can be very, very efficient and can scale to any number of users.
But...
Almost anything you want to do other than viewing static web pages will involve sessions and states. When HTTP is used for its original purpose (sharing static information like scientific papers) the stateless protocol makes a lot of sense. When you start using it for things like web applications, online stores, etc. then statelessness starts to be a bother because these are inherently stateful activities. As a result people very rapidly came up with ways to slather state on top of the stateless protocol. These mechanisms have included things like cookies, like encoding state in the URLs and having the server dynamically fire up data based on those, like hidden state requests, like ... well, like a whole bunch of things up to and including the more modern things like Web Sockets.
Here are a few links you can follow to get a deeper understanding of the concepts:
http://en.wikipedia.org/wiki/Stateless_server
http://en.wikipedia.org/wiki/HTTP
http://en.wikipedia.org/wiki/HTTP_persistent_connection
HTTP is stateless - this means that when using HTTP the end point does not "remember" things (such as who you are). It has no state. This is in contrast to a desktop application - if you have a form and you go to a different form, then go back, the state has been retained (so long as you haven't shut down the application).
Normally, in order to maintain state in web application, one uses cookies.
A stateless protocol does not require the server to retain information or status about each user for the duration of multiple requests. For example, when a web server is required to customize the content of a web page for a user, the web application may have to track the user's progress from page to page.
A common solution is the use of HTTP cookies. Other methods include server side sessions, hidden variables (when the current page is a form), and URL-rewriting using URI-encoded parameters, e.g., /index.php?session_id=some_unique_session_code.
here
HTTP is called a stateless protocol because each command is executed independently, without any knowledge of the commands that came before it.
This shortcoming of HTTP is being addressed in a number of new technologies, including cookies.
When it's said that something is stateless it usually means that you can't assume that the server tracks any state between interactions.
By default the HTTP protocol assumes a truly stateless server. Every request is treated as an independent request.
In practice this is fixed by some servers (most of them) using a tracking cookie in the request to match some state on the server with a specific client. This works because the way cookies work (they are posted to server on each subsequent requests once they have been set on the client).
Basically a server that isn't stateless is an impediment to scale. You need to either make sure that you route all the requests from a specific browser to the same instance or to do backend replication of the states. This usually is a limiting factor when trying to scale an application.
There are some other solutions for keeping track of state (see rails's encrypted state cookie) but basically if you want to grow you need to figure a way to avoid tracking state on the server :).
i am trying to create framework/library /API for creating small multiuser games, in which the goal is to achieve 'decoupling' between the server, client and business logic.
The server in my case is kind of registering the clients and sent that
list to business logic, clients are registering with the server,
and the business logic do the game logic stuff and updates the client by getting the list of client from server.
But currently,
i have only one class, so its trivial but this could consist of several game objects
(and what would be the role of classes serialized/remote
like the game engine, player, score, move, board).
i decided to use the RMI for this and this will definitely use callback
mechanism can somebody told me.
How could i achieve this encorporating all the requirement of server updating clients (callbacks).
PS:i m currently working on the design, which has one remote/serialized object for handling gamelogic but i wanted to
use other classes as i mentioned for sake of making multiuser game library and to show the use of important classes in it as an example.
thanks a lot
jibby
If you are intending this framework to work for real time games then I would advise against using RMI - it isn't really designed for that sort of thing. Also be aware that two-way RMI between machines on different subnets is very hard to get working.
It seems as if you need the clients to be informed by the server when events occur. When your client connects it can lookup a Remote object from the server's RMI registry and call a method on that to pass a Remote object it has created (hosted on the client) to the server. The server will have to maintain a collection of these client objects and iterate through them to send events. This is a tricky architecture to get right as if the network goes down or a client goes offline you will have to deal with all sorts of nasty error handling and freeze ups. I would recommend you keep the majority of communication in one direction - from client to server. Also keep it as simple as possible - simply a Remote object on the server with various methods that take Serializables as parameters and return Serializables.
Whether or not this is MVC depends on your interpretation. You could see the clients as views with the model and controller on the server in which case it is MVC with the event mechanism being a remote implementation of the observer pattern.
The trickiest part of the task will definitely be getting the code on the server that notifies the clients correct as it will need to be multi-threaded and handle errors gracefully - good luck!
I have a web-based application which makes use of remote EJBs for its business logic. Some of these EJBs are also exposed as Web Services. I need to keep a small state for some of these calls in order to allow subsequent calls to function correctly. Which of the following would you recommend?
Stateful EJBs (will this work with Web Services?)
Return the state to the client (what if I want to prevent the client from altering the state?)
Reload the state from the DB on each method (should I worry about the overhead?)
All three proposed solutions can be made to work, but the best solution will depend on the details of your application.
I don't use Stateful Session Beans (SFSBs) at all. SFSBs are designed to keep session state, but using them via a Web Service raises questions about what exactly is a session? If you have a complicated deployment environment or users use multiple instances of the application then this could be a fragile solution.
Returning state - as the question indicates, there could be security issues unless you are certain that the server can trust its clients. You could use encryption techniques to verify that the state object had not been modified, but it is much safer not to give sensitive data to a potentially hostile client. Another situation where this might be useful is if the client is permitted to alter the state, or if no harm can be done if the client does so. If client access to the system is always through a web-tier, this is a good place to store session state. The web-tier and application-tier can safely exchange state objects.
Reloading the state from the database is probably the most generally applicable approach. If you use an entity bean or an Object Relational Mapping library then the server should be able to reduce the number of database queries.
The only option you have is to store appropriate information associated with a certain UserId in the DB.
You can't expose Statefull bean as Webservice.
In case of exposing your Beans as Webservices you could try to send additional information back and forth by putting in the SOAP header to prevent modifications in the body. But in this case clients will be able to alter it.