I am new to Node.js and server-side JS in general.
I am coming from Java EE and I am used to use stateful objects (not EJB, I am using CDI), for instance, for MVC.
My aim is to keep some data that is tied to e.g. a session.
CDI in Java EE knows the following state scopes:
Application scoped (= same as the singleton pattern)
Session scoped (state is kept for a user's session lifecycle, e.g. the logged in user)
Conversation scoped (state is kept for an identified conversation, e.g. a shopping cart)
Flash scoped (state is kept between two requests)
How to do all that stuff with Node without using a database, just using stateful objects?
You'll need something like connect to track session state for you as that is the least-trivial of these scopes. Once you have that you can do things as follows.
Application scoped (= same as the singleton pattern)
set a property on your HTTP server instance: myServer.totalRequestsServed = 0
or you can use a process-wide global: global.totalRequestsServed = 0
Session scoped (state is kept for a user's session lifecycle, e.g. the logged in user)
use the connect session middleware for this: req.session.user = myUser
Conversation scoped (state is kept for an identified conversation, e.g. a shopping cart)
I'm not totally clear on what you mean by "conversation scope" but I would stick this on the session user or in a shared hash object. session.user.shoppingCart = {}
Flash scoped (state is kept between two requests)
Use either the session or the request for this. There are existing modules in npm to give you helpers like req.flash("Welcome!"). See connect-flash for example.
Just like in the Java world, to be scalable, you'd need either server affinity or an external store for session data. Storing session scoped data on the server (as well as replicating it across all clones) is not scalable.
Server affinity can be arranged at infra level via a cookie. No change needed in the application.
External store support in NodeJS is available via the express-session middleware. It supports a number of session stores out of the box.
Related
Is there any relationship between stateful session bean and HTTP session ?
What are the use cases where we would require a stateful session bean and what use cases requires HTTP Session.
Can i expose a stateful session bean as a restful web service ?
HTTP is a stateless protocol Which means that it is actual transport protocol between the server and the client -- is "stateless because it remembers nothing between invocationsNow First read this what is HTTPSession and what is Session Bean (keep in mind that session beans are use to maintain the data state across multiple request so mostly a session bean is a stateful session bean because it holds data across whole session)
HTTP Session
An HttpSession object can hold conversational state across multiple requests from the same client. In other words, it persists for an entire session with a specific client.
We can use it to store everything we get back from the client in all the requests the client makes during a session.
Session Bean from wiki
In the Java Platform, Enterprise Edition specifications, a Session Bean is a type of Enterprise Bean.A session bean performs operations, such as calculations or database access, for the client. Although a session bean can be transactional, it is not recoverable should a system crash occur. Session bean objects either can be stateless or can maintain conversational state across methods and transactions. If a session bean maintains state, then the EJB container manages this state if the object must be removed from memory. However, the session bean object itself must manage its own persistent data.
In Simple words
Session tracking is the process of maintaining information, or state, about Web site visitors as they move from page to page. It requires some work on the part of the Web developer since there's no built-in mechanism for it. The connection from a browser to a Web server occurs over the stateless Hypertext Transfer Protocol (HTTP) AND
SFSB's are designed for managed client state over multiple calls to the same session bean (i.e. a conversation). If you look at JBoss Seam, you will see that there is very heavy use of SFSB's for conversation context.In EJB3, there is no such thing as "stateless is better than stateful session beans". For example, one provides a service like a credit card processor (stateless) and one provides processing for a multi-screen wizard use case (stateful). In My opinion Managing state using HttpSession and stateless session beans is very difficult and problematic.
EDIT: HTTPSession is use to keep the session tracking like A user sessionFor example You want to create a Login , Logout mechanism then You must need the HTTPSession because when The user will start navigation between different pages then this HTTPsession will remember that WHO is asking for the pages otherwise it is not possible(because HTTP is a stateless protocol) Now In session you just set the session of username and password and you are checking on every page that if this session exists then show the pageNow what if , You have to send a lot of information of this user across multiple requests? In this scenario, You will set all this info in a Stateful session bean But now a days , In modern frameworks session as well as information , everything is stored in Session beans because From session bean it is easy to manage them. HTTPSession was used when we were purely on Servlet and somehow JSP technologies
This is not a simple question its just because i'm rethinking our architecture for securing our EJB 3.0 service by a login and security.
We have a EJB3.0 application on JBoss 5.1 that offers various services to a SWT client to read and write data. To use a service, the client must login with a valid user and password which is looked up by SpringSecurity in a LDAP server. SpringSecurity generates a session id which is passed back to the client to be resused in any further service call.
client server
| |
|-> login(user/password)-------->|
| |
| <------- sessionId ------------|
| |
|-->serviceXy(sessionId,param1)->|
The situation seems clear. We store the sessionId in our own context object which is the first parameter of each service method. There is an interceptor on each service method which reads the sessionId from the given context object and checks if the session is still valid. The client needs to call the login service first to get a context object filled with the sessionId and reusue this context object in further service calls.
public class OurContext {
private String sessionId;
}
#Stateless
#Interceptors(SecurityInterceptor.class)
public OurServiceImpl implements OurService {
public void doSomething(OurContext context, String param1) {
[...]
}
}
The thing i don't like at this solution is the polution of each service method with the context parameter.
Isn't there a similar mechanism like a http session in rmi calls? I'm thinking of putting our context object in some kind of session that is created in the client(?) right after the login and is passed to the server on each service call so that the SecurityInterceptor can read the sessionId from this "magic context".
Something like this:
OurContext ctx = service.login("user","password");
Magical(Jboss)Session.put("securContext", ctx);
service.doSomething("just the string param");
Since you are already using an app server, it seems that you should be using the built-in EJB security mechanisms, generally provided through JAAS. On the 4.x jboss line, if you implemented your own JAAS plugin for jboss, you could get access to a "special" context map (similar to what you describe) which is passed along on remote requests (by the jboss remote invocation framework). I haven't used jboss in a while, so not sure how this maps to the 5.1 product, but i have to imagine it has similar facilities. This assumes, of course, that you are willing to implement something jboss specific.
There are some kinds of session mechanisms in EJB, but they all start when the remote call starts, and ends when that ends. On old one is the transaction context ( Adam Bien wrote about this some time ago), and a newer one the CDI Session Scope.
Contrary to popular belief, this scope doesn't just mirror the http session scope, but in absence of an http session (like for remote calls), it represents a single call chain or message delivery (for mdbs).
With such a session, your remote SWT client still has to pass the sessionId to the remote service, but any local beans called from there can pick it up from this "cdi" session.
The other option is kinda like what jtahlborn says: with your own login module you can return a custom principal, instead of the default one. Your code can first request the normal principal and then try to cast it.
The problem is that this stuff is container specific and JBoss always forgets about it. It pretty much breaks after every update, and users have to kick and scream to get it fixed in some next version (only to see it break again in the version after that). Without JBoss really supporting this it's an endless battle.
Yet another option is to let the user login with the sessionId as name. The login module behind that could be a simple module that accepts everything and just puts a principal in the security context with the sessionId as 'name'. It's a little weird, but we've used this succesfully to get any data that can be expressed by a string into the security context. Of course, you would need to let your client do a regular container authentication here, which kinda defeats using Spring security in the first place.
We went for another approach which is portable and does not rely on a specific app server. In addition our security implementation frees us from the restrictions of the EJB approach (which by the way I thought were closed 2 decades ago ... but came up again).
Looking top down:
There is a server providing classes with methods to work on same data.
The client(s) provide the data and invoke specific methods.
Our approach is to put all data (and therefore communication between client and server) into a "Business Object". Every BO extends a superclass. This superclass contains a session id. The login method provides and returns that id. Every client only has to ensure to copy the id received in one BO into the next one it sends to the server. Every method which can be remotely (or locally) invoked, first obtains the session object with the received id. The method to return the session object also checks security constraints (which are based on permissions and not on roles like in the EKB approach).
I have a web application in which we use JSF framework.
I have been diving deep into the security part for web application and hence I was looking to generate my own unique session ID(using encryption algorithm and assign it to every new session which gets created once user logs in.
Can anyone please guide me on how to set manual generated session id in session and ensure with each request that session id is transmitted.
Thanks.
I really doubt you'll generate session IDs that are more secure than the ones generated by the container, but here's what you could do, without using any container-specific extension.
Create a servlet filter which intercept every request to the server.
When a request comes in, check if a session already exists for this request (using getSession(false)). If one exists, then extract your specific cookie MY_SESSION_ID from the request, and compare its value to the one that is stored in the session. If they don't match, reject the request.
If the session doesn't exist, then create it (using getSession(true)), generate your super-secure session ID, store it as a session attribute and add the cookie MY_SESSION_ID to the response.
This has the disadvantage of creating a session automatically, even if it's not strictly needed. But that's the case most of the time when using JSPs of component frameworks.
Attempting to do this at the JSF application layer is unlikely to be successful; I would perform this task at a lower level API. I am assuming a servlet container.
I can think of two approaches:
do this at a container level via a server-specific SPI (if one even exists)
do this by rewriting requests/responses via a servlet Filter
There is insufficient information to comment on the viability of the first approach.
In the second, you would have to determine the name of the session cookie (it is usually JSESSIONID, but does not have to be). Your API would:
map the filter to all application requests
maintain a map of container session ids to "secure" ids
use the filter to rewrite any session cookie in the request with the session id
use the filter rewrite any session cookie in the response with the secure id
use a listener to remove invalid sessions from the map to avoid memory leaks
A new corporate policy on Secure Coding was recently put into effect. The initial audit assessment tagged me deficient for:
Session state must be managed such that a session will withstand replay-attacks.
I'm not exactly sure what this statement means or why I am defecient in it. I'm developing a Java Web application and set a session as such:
session.setMaxInactiveInterval(36000);
Session state must be managed such that a session will withstand replay-attacks.
The statement is way too confusing. Rewording it would yield:
The session management framework must protect the application against replay of session IDs.
It is less confusing (hopefully), and continues to carry the same meaning as the former (again, hopefully).
Typically, if one were to implement a home-grown session management framework instead of relying on the one provided by the container for instance, then it is quite possible that the session management feature of the application would be susceptible to a replay attack.
A session replay attack would involve the scenario where the session ID is replayed back in a request, after the session has expired. A well written session management framework would recognize that the provided session ID is not a valid session ID. However, there have been instances where a vulnerable session management framework accepted the now-expired session ID, and recreated the contents of the session. In worser scenarios, the session management framework did not destroy the session at all, on session expiry, resulting in the scenario where a session ID replay resulting in requests being processed.
It must be remembered that even normal users of the application may unintentionally perform session-replay attacks, if they are able to browse to protected pages in the application without logging in. This is an indication of a failure in the authentication and the session management features of the application, for the app should ideally allow users to browse protected pages only after successful authentication, which would yield a token (a session ID) that may be used for a certain duration to access the site without further authentication. If you are using persistent cookies for authentication, you may have unintentionally introduced a hole.
Going by the above, one can protect any application from session replay attacks by:
Ensure that you are using the container provided session management features. From the use of the session.setMaxInactiveInterval I would assume that you are it. But, to be sure, verify if you are creating session IDs using other means, or for that matter, verify if you are using identifiers that are equivalent to session IDs. In simpler words, ensure that your application relies only on the value of the JSESSIONID cookie (or the equivalent as configured in the container) to communicate session IDs to the browser. Also, verify if persistent cookie are in use (refer the above posted scenario).
Invalidate the session after a certain idle period. If you do not invalidate the session, then an attacker has a larger time window to brute force the session ID. From the point of view of session-replay attacks, this is worse since the attacker can replay back a compromised session ID at any point in time, and still get access to a valid user session. You would also want to revisit the duration specified in the session.setMaxInactiveInterval for the value you are using currently is 10 hours. I would consider that to be insecure. Most applications do not require a rolling window of session expiry beyond 30 minutes, with 10 minutes being the value recommended for high-value apps.
Destroy the server-side session and it's contents on expiry. In a servlet container, this is typically done by invoking session.invalidate() in a logout page/link. Ensure that you have provided users with a link to logout from the application in the first place, so that the logout request can be processed to invalidate the session using the before-mentioned API call. If you do not perform this activity, the server-side session object will be destroyed only on session expiry (which will occur after 10 hours of inactivity by the user; now you see why 10 hours is a bad idea).
this is to do with something similar to session hijacking.. where the auth token is held by a hacker to login at a later stage..
in my projects i've added a simple filter which does the following.
every jsp page which is responded would be given an attribute called id (the token is generated using UUID().. the same token is placed in the session..
when a page is posted, the filter (which is configured to filter all requests) checks for the equality of these tokens & proceeds only if the values match.
we also added a timestamp in the session & the database, whenever a page is submitted we check the time stamps in the session with the db.. if the number is within 10 ms then the request passes, else the user is redirected...
I have a Java EE application consisting of 1 web module and 1 EJB module. Inside my EJB module I have a stateful session bean containing my business logic.
What I would like is:
When a user logs in to my web application and creates a new session in the web tier I want that user to be assigned an instance of my session bean.
At the moment a session is being created in the web tier as expected but I am unsure about how to map the session in the web tier to a new EJB session each time. Currently I am invoking my EJB from my Servlet meaning that only 1 instance of the bean is being created. I am trying to get a 1-1 mapping between web sessions and sessions in my EJB layer.
I know this could be achived easily using application clients but any advice / design patterns on how I could achive this in the web tier would be greatly appreciated.
Stateful Sessions are not always a good choice, sometimes using persistence to a DB is easier.
In the servlet, as process a request from a user, obtain the "handle" to your SFSB. Put that "handle" into your HttpSession. Now when the next request for that user arrives you have the handle ready.
With EJB 3.0 do it like this.
Declare the bean reference with #EJB at class scope, this sets up the reference you'll use later
#EJB
(name=“CounterBean", beanInterface=Counter.class)
public class MyStarterServlet …
When you process the request: access the EJB using JNDI and the declared bean name, note that this code is in your doGet() and/or doPost() method, the "counter" variable must be local (on the stack), as the servlet object is shared between potentually many requests a the same time.
Context ctx = new InitialContext();
Counter counter = (Counter)
ctx.lookup(“java:comp/env/CounterBean”);
counter.increment();
Store the interface in the HttpSession object to retrieve as needed
session.setAttribute(“counter”, counter);