I have web client which invokes multiple services. As soon as the user is authenticated, I want to store the email Id somewhere as it sends the email Id for each request.
I don't want to use session as I have heard that is the best practice. In REST, all data must be sent for the request and it must be stateless. What other alternatives are there? Is using DB for session management still not breaking the stateless principle of REST?
I went through If REST applications are supposed to be stateless, how do you manage sessions? but there were many contradicting opinions there. Should the email Id be stored in session storage of the browser then?
I think you should do it with a authentication header. Check out these threads:
Do sessions really violate RESTfulness?
If REST applications are supposed to be stateless, how do you manage sessions?
Related
If microservices are stateless , how can we manage session in JSP based projects .Assuming I am breaking age old monolith to microservices .
You can't manage session in a stateless server.
What you can do is that storage a unique token and its corresponding information into Redis/MemCache.
You need to storage the token instead of JSESSIONID in client.
The fact that most implementations of microservices in the industry communicate via HTTP does not mean that microservices are meant to be used as web servers.
A microservice:
does not have to communicate via HTTP (though most implementations do, for convenience)
is not meant to receive requests issued by a web browser (although you can use a web browser to issue requests to an HTTP-listening microservice to test it)
is certainly not meant to generate responses containing HTML that can be rendered in a browser.
For these reasons, microservices generally do not have a concept of a session.
If you absolutely must make your microservice session-aware, and retain it stateless (so that it can still be legitimately called a microservice) then you have to have it fetch all necessary session information from your persistence store each time a request arrives, and save whatever parts of it have changed back into the persistence store right before returning its response. But that's not how microservices are meant to work.
Generally, the way we use microservices on the web is as follows:
Either we have javascript running on the browser which maintains session state and issues sessionless requests to the microservice, containing authentication information if necessary, [*] or
We build a conventional web server which maintains session state the traditional way and is therefore not a microservice, and we have that web server internally issue sessionless requests to microservices in order to do its job.
Footnote:
[*] please note that my acknowledgement of the fact that many people do this does not in any way constitute an endorsement of this practice.
So I am building a REST-API using Spring for a simple game. I now have the need to be able to track a user together with some data (what games they're in and on what team). I got some tips that Spring security might be worth checking out, however I fail to see how that would help me without necessitating a login.
Are there any good methods for doing this?
I've also tried using the session which can be gotten from HttpServletRequest, however this session differs from the first navigation to the webpage, which I was not able to resolve and I'm worried that it would be too unreliable.
REST is supposed to be stateless. That means you don't really want to have a session for stuff like user data. This should all be persisted server side and managed via rest calls. You would have a User resource and a Game resource and perhaps a relation between them, all held in a database. Spring Security is not going to help you with any of this.
What Spring Security might be able to help you with is securing your REST services and managing identity. Although REST is stateless, it is normal for a client to send something like an access token in a HTTP header. This access token provides both identity and authentication. Again, you will need to separately manage and store the relationship between the access token and the user server side, perhaps in your database.
Session can be fetched from HttpSession and not HTTPServeletRequest. HttpSessions are reliable.
I have a web service which authenticates a user, and if successful gives them a JSON Web Token which they can use to persist their session.
Currently I only have one server, but would ideally like to increase that to two or more for the sake of performance, however I'm unsure as to how that'll work with different servers as they'll have different instances of maintaining who is currently logged in.
For example, my service will examine the JWT the client returns, and (assuming it's a good token), will take the user ID and session and check if there is a user logged in with that session ID.
However, if for example, the middleware that precedes the web service layer determines that the server the user was initially logged in is currently unavailable and routes the request to a different server instance of the web service, how is the authentication controller meant to evaluate if the request is valid?
A very basic version of my service can be found below, with the black arrows representing ordinary communication, and the red arrows representing communication in the event that Layer One decides to route the request to Instance Two.
Layer One, in essence is very basic and doesn't really do anything other than route traffic to the next layer dependent on the availability of the layer two instances.
One of the main advantages of JWT is that it does not need server storage because it is self-contained and stateless. If you need server sessions may be JWT it is not your best option to manage authentication. See Stop using JWT for sessions
Currently application servers use the SESSION ID to manage load balancing and redirection to the server that store the user session, including persistent storage and migration of session. Using a JWT you won't take profit of these characteristics.
Use JWT if you need a REST stateless endpoint with authentication or you need to exchange data securely between parties
My understanding is that a RESTful service should be totally stateless. Every time I invoke the service, I must pass all the information it needs to operate properly.
However, when it comes to authentication I get rather confused about how this should work, particularly in terms of session management.
I am using basic authentication and the first time I make a request, the client gets challenged (or I can pass the authentication information in the header from the beginning). But once the user has been authenticated, the server will not challenge this client anymore as long as the session is alive.
This means that I need to provide some mechanism for the current user to logout (terminate his/her session).
It would look like the right way of doing this would be to change my configuration somehow so that every request is challenged for authentication, but I have no clue how this plays with session management.
Am I supposed to invalidate the session manually after every request?
Or is there way to force the clients to be challenged every time a request is made?
You can find lots of questions out there about security with REST, and even books about how to implement different models of authentication. But I have not found a good answer on how to deal with session management, logging in and out. So either I am doing something wrong or I am misunderstanding something important here.
I would appreciate any thoughts or guidance on how this should be properly handled.
I am using Jersey 2.4 with Tomcat 7.
If you're authenticating with HTTP Basic, the client is challenged the first time only because the Authorization header isn't being sent from the client. Once it's sent and the server sends something other than a 401, the client caches those credentials and re-sends them with every request.
You shouldn't create sessions in a stateless app, not only because they aren't used, but because they require overhead to manage (even empty ones). The servlet architecture, however, cannot prevent code from creating sessions, such as when the code calls either httpServletRequest.getSession() or httpServletRequest.getSession(true). So you need to ensure that you don't use any code (or frameworks) that do this.
Interestingly enough, Tomcat will still generate a JSESSIONID cookie for the client to use, and under most configurations of the container, you can't turn this off. However, if sessions aren't created, the cookie is essentially ignored (and a new JSESSIONID cookie will be generated on every request).
And, because the app is stateless, there is no concept of login or logout. All authentication is done per request.
Note that, depending on your particular app, pragmatism may trump pure RESTfulness. There are cases where "a little bit" of server state is really the only way to provide some types of security to the app (such as cross-site request forgery, anything with nonces, etc.)
If you are doing a RESTful webservice you shouldn't handle sessions.
The first time you connect to the API you need to pass the authentication check in order to obtain an authentication key.
This key is how your API will identify its users.
You shouldn't invalidate the session and you shouldn't force your users to re-authenticate.
I want the clients of several related web apps to hold their own authentication state. This improves scalability, because no session replication between cluster nodes is needed. And it makes integration of different server technologies like Java Servlets and PHP easier.
My plan is as follows:
Set a signed and encrypted cookie with the user name and session expiration time after client authentication.
When the client sends a request, the server decrypts and validates the cookie and grants or denies access depending on the cookie values.
The session expiration will be updated through resetting the cookie.
All servers that want to use the session have only to know the cookie mechanism and the decryption key. See also: Session state in the client tier
Is this approach ok? Would it be possible to integrate it into a servlet container / application Server so that it is transparent to the applications? A servlet should be able to use HttpServletRequest#getRemoteUser() for example. Is this possible? Or would I need something above the container level like Spring Security? Are there any existing libraries for client side session management?
Not a good idea. Storing vital data like session expiry and user name entirely on client side is too dangerous IMO, encrypted or not. Even if the concept is technically safe in itself (I can't answer that in depth, I'm no encryption expert), a break-in could be facilitated without compromising your server, just by acquiring your encryption key.
Somebody who gets hold of the key could generate session cookies at will, impersonating any user for any length of time, something the classical session concept is designed to prevent.
There are better and scalable solutions for this problem. Why not, for instance, set up a central session verification instance that all associated servers and services can poll? Look around on the web, I am 100% sure there are ready-made solutions addressing your needs.
I disagree with the posters saying this approach is not secure. Variants of it are used in a number of well respected frameworks, such as Rails and Play!, for precisely the reasons you outline, and it's perfectly secure when implemented correctly.
This improves scalability, because no session replication between cluster nodes is needed.
First, using HTTP Session doesn't really prevent you from scaling, even when using HTTP Session State replication (some mechanisms are smarter than others by the way, for example WebLogic's in-memory replication doesn't have a big overhead). Second, do you really need it? Most applications (the majority) don't need Session replication. Third, am I understanding right: do you plan to not use HTTP Session at all?
(...) Set a signed and encrypted cookie with the user name and session expiration time after client authentication.
Don't do this! Don't store a username and other sensible data used by the server in a cookie, this is a very bad idea! You actually need to admit that it's just a matter of time before someone figures out how your system works and breaks it (especially if your cookie is candidate for crib attacks). Sor, really, you should store data in the Session on the server-side and only an ID in the cookie, like things are actually working. This is much more secure.
Is this approach ok?
No. And you don't need this for interoperable single-sign on (if this is what you are trying to build). Just use a centralized authentication solution like CASJasig which has libraries for various technologies.
This is not really how Sessions are implemented. The cookie itself doesn't need to carry any data of the session itself, it's just a reference to it.
What the Cookie holds is usually a Session ID which is then linked to the data on the server.
If you don't have a central data session server for the other servers to access, I suggest to get one :).
You can avoid duplication of data in a clustered environment by using a state server - a server that is well known by all the nodes in the clusters and maintains the session data for all the users. Every time a user performs a request, it send a cookie with session id to the applications server; this one should retrieve the session from the state server. This is possible for asp.net development, but I'm not sure how easy Java supports this approach.
As Pekka said, not a good idea. One can intercept your cookie with sensitive session data. Even with SSL, by using fiddler2 one can decrypt the traffic