HttpSession for microservices - java

I understand that token based authentication is widely used for microservices, esp, when there is horizontal scaling.
For microservices also, can we use sessions by storing it in database?
The series of requests would be :
First request, HTTPsession is created and session id stored in a database table along with unique
username.
Second request is sent with this session id, and any
microservice instance can serve this request. Server has to verify
this session and user with that of the database record. If sesssionid+username combo is present in database and sessionid is a valid one, then serve the request else redirect to login page.
When logout is clicked, session is invalidated and db record is also removed.
Will this not be a good session management for microservices?
Do Microservices always have to be stateless?

The reason token based authentication is used for microservices, is to avoid having to share session state between the services.
If you specifically refer to an implementation of the javax.servlet.http.HttpSession object, this is normally local to one server (service) and it would take some custom code to reload this based on the session id provided, if at all possible in your particular runtime (don't know what software you are using).
I don't see why your suggestion wouldn't be possible though, but I would carefully consider if it is an absolute requirement. There might be other, simpler, ways to achieve what you want.
One way of doing it would be to issue a token (JWT comes to mind) when logging in, and having the other services simply verify this token and extract the user data from it. This way no lookup of user data is required for authentication after the first login.
If shared state is what you need, I would suggest finding some existing software to handle the session storage. I see that for instance Redis has a solution for session management.
Also you may check out the answers to this question

Related

Is there a way to access session data that was set in the openid connect process?

When I try to access Liferay Portal session data it seems as it doesn't contain data stored by internal Liferay Portal processes. Is it possible to access the token that was stored in the OpenId-Connect Login process?
Basically, I was tasked with finding Software, that can make implementing a Portal, which displays functionality offered by API-Endpoints of multiple different internal Platforms easier. Currently, I'm looking at Liferay Portal 7.2. For the Login, I've used the OpenId-Connect implementation of Liferay Portal since authentication is handled by an internal Login server. The access token returned at the end of the OpenID-connect login process is an API-Token which I then want to use to access various API-Endpoints.
Currently I get the Session like this
HttpSession httpSession = PortalUtil.getHttpServletRequest(actionRequest).getSession();
After looking at the OpenId-Connect implementation in
com.liferay.portal.security.sso.openid.connect.internal.OpenIdConnectServiceHandlerImpl
I then tried to get the Session Object like this.
Object openIdConnectSessionObject = httpSession.getAttribute("OPEN_ID_CONNECT_SESSION");
But at this point, openIdConnectSessionObject is always null. I have read that different scopes have different sessions, but is there a way to access this data or is Liferay Portal maybe not really fit for what I'm trying to do.
There's one detail worth noting:
PortalUtil.getHttpServletRequest(actionRequest) will give you access to an artificial PortletRequest object that adheres to the HttpServletRequest interface, in case you need that for some API that expects requests from the servlet, not the portal, world.
A PortletRequest contains only parameters (and session information) directed to a particular portlet, and nothing else.
If you're interested in the actual underlying HttpServletRequest, you'll need PortalUtil.getOriginalServletRequest, which takes an HttpServletRequest as input. And you'll get that the way you've already explored. In the end, you'll have
session = PortalUtil.getOriginalServletRequest(
PortalUtil.getHttpServletRequest(actionRequest)).getSession();
to get the actual server's session.
I've not checked if that is useful, or even an advisable solution to the problem you state, but it might bring you further along solving your problem.

Remember me Login page with JSP Servlet using database at backend? [duplicate]

I'm using OpenID. How do I make it so that the user stays logged in for a long time even after closing the browser window?
How do I store and get access to the user's User object?
Basically, I guess I just don't really understand how sessions work in Java.
So you actually want like a "Remember me on this computer" option? This is actually unrelated to OpenID part. Here's a language-agnostic way how you can do it:
First create a DB table with at least cookie_id and user_id columns. If necessary also add a cookie_ttl and ip_lock. The column names speaks for itself I guess.
On first-time login (if necessary only with the "Remember me" option checked), generate a long, unique, hard-to-guess key (which is in no way related to the user) which represents the cookie_id and store this in the DB along with the user_id. Store the cookie_id as cookie value of a cookie with known cookie name, e.g. remember. Give the cookie a long lifetime, e.g. one year.
On every request, check if the user is logged in. If not, then check the cookie value cookie_id associated with the cookie name remember. If it is there and it is valid according the DB, then automagically login the user associated with the user_id and postpone the cookie age again and if any, also the cookie_ttl in DB.
In Java/JSP/Servlet terms, make use of HttpServletResponse#addCookie() to add a cookie and HttpServletRequest#getCookies() to get cookies. You can do all the first-time checking in a Filter which listens on the desired recources, e.g. /* or maybe a bit more restricted.
With regard to sessions, you don't need it here. It has a shorter lifetime than you need. Only use it to put the logged-in user or the "found" user when it has a valid remember cookie. This way the Filter can just check its presence in the session and then don't need to check the cookies everytime.
It's after all fairly straight forward. Good luck.
See also:
How to implement "Stay Logged In" when user login in to the web application
How do servlets work? Instantiation, sessions, shared variables and multithreading
Well, the original reason I chose OpenID was so someone else could handle as much of the implementation and security of authentication for me.
After looking into OpenID more, it appears there is something called an "Immediate Request" (http://openid.net/specs/openid-authentication-2_0.html#anchor28).
When requesting authentication, the Relying Party MAY request that the OP not interact with the end user. In this case the OP MUST respond immediately with either an assertion that authentication is successful, or a response indicating that the request cannot be completed without further user interaction.
Because of this I think I could just store the user's openID url in the cookie, and use an immediate request to see if the user is authenticated or not. This way I don't have to do anything with my database, or implement any logic for preventing session hijacking of the long-lived cookie.
This method of doing it seems to be the way OpenID suggests to do it with their Relying Party Best Practices document.

Storing data as a cookie in the browser vs. session

I am trying to learn more about JAVA web development. I am mainly focused on trying to understand how data that a user enters, maybe through the course of filling out a multipage form, is managed as the user moves from page to page.
From what I have gathered, you can store data within the session on the server side. I am also learning about cookies which are stored within the browser. Is there a general rule that is used to determine what data should be stored in a cookie vs. when you should store data in a session (session.setAttribute), or are these completely different concepts?
Thanks
The basics of session/cookies are like this.
A session is typically a way for a server to store data about a user. This can be done in a variety of ways from memory, file to database. This session can be used by you store pretty much anything you need to have as the user bounces around your site. It is assigned an ID (the session ID) which you don't usually need to worry about too much. In most web languages you can easily access the user session with some functions without dealing with IDs.
Now since the web is stateless - meaning there is really no way to know that user that visited page A is the same as the one that visited page B then we want to make sure that the user carries their session IDs with them. This can be done in a variety of ways but the most common one is through the use of a session cookie which is a special cookie automatically set by the server that is solely there for passing the session around. It can also be passed in the URL (I'm sure you've seen things like index.php?sessid=01223..) as well as headers and so on.
When most people talk about adding info to a cookie they are not talking about session cookies but about a custom cookie that you specifically set. The only reason that you would want to do that is if you needed to store info beyond the life of the session (which ends when the browser is closed). A good example of that is the "remember me" feature of many sites.
So use sessions unless you need to have something last a long time.
Yes. There are a few rules actually. For one, cookie data is sent by the browser on every request; session data is kept on the server (and not re-transmitted every request). However, usually the session id is used with a coookie. This enables the server to identify the client.

Is it safe to store critical data in HttpSession?

I store user data such as name, password and email in your HttpSession with setAttribute.
I want to know if it is safe to store critical data in HttpSession.
Try storing login information in one of the following user repositories (checking the validity while logging in):
In-memory (say, it could be an xml file),
JDBC-based,
LDAP-based.
It's not the full list of the authentication options.
You should at least use SSL/HTTPS for login and any other sensitive data.
Take a look at this article: http://en.wikipedia.org/wiki/Session_hijacking
And here is a nice SO discussion on that issue: What is the best way to prevent session hijacking?
Some security issues are also mentioned here: What should every programmer know about web development?
Ideal practice is to NEVER save passwords in any means of the application. Ideally passwords need to be saved encrypted in the DB's user table if you use db based authentication or use LDAP authentication.
After being successfully authenticated, you can keep the fields such as email and name in the http session. Its best that the username is kept (which is unique) in session and profile information has to be read from the database based on this username by performing a database read.
can keep this information in a cookie to facilitate repopulating frequent visitors with some information as well.
most important thing is to NOT save passwords in hidden variables,cookies or query strings AT ALL.
any sensitive information that MUST be kept must be in a SESSION but encrypted.

Using sessions in GAE/J

I'm having a hard time piecing together the various threads I've read on the topic, so I'd love to know if I'm on the right track before I get too far. I'm trying to make persistent logins using sessions and cookies and the like. At this point, I feel I've got my head around the login sequence, right now I just have a user db, but I'll try to tackle OAuth at a later date.
Login:
User enters credentials
Creds are sent async to server (ideally via SSL, eventually)
Passwords are never stored, only hashes are kept
If creds are OK, server sends the value of this.getThreadLocalRequest().getSession().getId() back
Callback method saves sessionID in a cookie and modifies the UI accordingly
(logout method clears the cookie and calls this.getThreadLocalRequest().getSession().invalidate())
I get lost when I want a user to be able to come back and pick up where they left off without having to log back in. I get the sessionID back from the cookie (if there is one), and then I somehow need to ask the server to verify it's valid. Is there a method that takes a session ID and returns whether it's a valid session? Or do I somehow tell the current session to use that ID?
The end goal is that I want to include the session ID in RPC calls that should be restricted to logged in users, and the server side methods will validate the sid received by RPC before running. I don't have to keep a running list of valid sids, right? That's already being handled by GAE (yes, I have the <sessions-enabled> set)
getSession returns a session object that can be used for persistent storage across requests. It already uses cookies to persist the session ID between requests. You don't need to get the session ID and store it separately in another cookie.
If you want to associate data with the user in the DB, either associate it with the session ID (eg, include the ID in the entity and look it up by ID) if you want it to be scoped to just the current session, or associate it with the user ID.
Unless you have a really, really compelling reason to invent your own user management, though, you really should be using the built in Google Accounts or OpenID support. You're not doing your users a service by forcing them to create yet another account for your site.
this.getThreadLocalRequest().getSession(false)
Returns the current HttpSession associated with this request and returns null in case it has no valid HttpSession.

Categories