how to forward session from one servlet to another? - java

Hey guys i'm working on admin module for my project. When a person logs-in, a request is sent to login servlet. When it further ask for some other report by clicking other options a request for the report is sent to other servlet which gives the result on the page which is shown at the time of user which is of normal type. The session is lost between two servlets.
I am trying to navigate the generated report on some other page but for that i need to know user type in second servlet. This can be done by fetching value of user_type from login module bean class.
How to handle this situation? thanks
My login servlet is :
LoginService user = new LoginService();
user.setUserName(request.getParameter("username"));
user.setPassword(request.getParameter("password"));
user = UserDAO.login(user);
if (user.isValid())
{
HttpSession session = request.getSession(true);
session.setAttribute("currentSessionUser",user);
if(user.getUser_type().equalsIgnoreCase("admin")){
response.sendRedirect("administrator/homepage.jsp");
}else{
response.sendRedirect("homepage.jsp"); //logged-in page
}
}
else
response.sendRedirect("invalidlogin.jsp"); //error page
}
i tried using this in second servlet:-
LoginService session = (LoginService)request.getAttribute("currentSessionUser");
String drake = session.getUser_type();
System.out.println("usertype = " +drake);
Here LoginService is the bean class of login module. i'm get a nullpointer exception here.

I think you're trying to do stuff that your web container should handle for you... A session should automatically be maintained over the course of multiple servlet calls from the same client session. Methods from HttpServlet are given a HttpServletRequest. You can obtain the corresponding HttpSession using one of the getSession methods of that class.
You can bind stuff to the HttpSession using setAttribute and getAttribute.
EDIT: I'm taking this from the Servlet spec 2.5:
A servlet can bind an object attribute into an HttpSession implementation by name.
Any object bound into a session is available to any other servlet that belongs to the
same ServletContext and handles a request identified as being a part of the same
session.
I think you're better off getting the HttpSession object from the HttpServletRequest (at least assuming it's a HttpServlet) and setting/getting attributes through that. If you choose a proper name (it follows the same convention as Java package naming) for your attribute, you can be sure the returned object, as long as it's not null, can be cast to whatever type you put in there. Setting and getting attributes on the request itself isn't gonna help, I don't think stuff will get carried over from one servlet call to the next unless you call one servlet from the other with a RequestDispatcher, but that's not what you're after here.
So in your second code sample, do (LoginService)request.getSession().getAttribute("currentSessionUser");, that ought to work. Make sure to check for nulls and maybe choose an attribute name that uses your project's package name convention (like com.mycompany...).
I wouldn't mind a second opinion here since I'm not much of an EE/web developer.

Related

SessionAttributes when open new browser tabs

I have an Spring-mvc application and in each controller I add a form to SessionAttributes to preserve properties when save, delete or do another get request. Main problem becomes when I try to open some link in another browser tab and try to submit the first one. I tried this solution but when I do a redirect (in controller I only have 1 return for view and the other methods do a redirect) it creates a new conversation and can't find previous one.
I have another question about this triying to use spring-session, question It's here but I don't know if this will work too.
Did you look into Spring's RedirectAttributes? I haven't used it myself but it sounds like it should do what you would like. RedirectAttributes is typically used for GET/redirect/POST patterns and at least one user seems to think passing session attributes this way is bad practice, however they go on to mention there doesn't seem to be a better solution. Anyway, the example shown in the documentation:
#RequestMapping(value = "/accounts", method = RequestMethod.POST)
public String handle(Account account, BindingResult result, RedirectAttributes redirectAttrs) {
if (result.hasErrors()) {
return "accounts/new";
}
// Save account ...
redirectAttrs.addAttribute("id", account.getId()).addFlashAttribute("message", "Account created!");
return "redirect:/accounts/{id}";
}
would add the "message" attribute to a RedirectModel, and if your controller redirects, then whatever method handles the redirect can access that data like so:
#RequestMapping(value = "/accounts", method = RequestMethod.POST)
public String handleRedirect(Model model) {
String message = (String) model.asMap().get("message");
return new ModelAndView();
}
So adding session attributes should be possible in the same way. Another reference here.
EDIT
I was looking through the Spring documentation and they also mention this annotation #SessionAttributes. From the documentation:
The type-level #SessionAttributes annotation declares session attributes used by a specific handler. This will typically list the names of model attributes or types of model attributes which should be transparently stored in the session or some conversational storage, serving as form-backing beans between subsequent requests.
Could this be what you need?
And also a link to documentation on flash attributes.
This is the solution we have come up with, nothing to do with Spring:
On each html form of your application you will have to include a hidden field. Let's name this field CSRF_TOKEN. This field should have a randomly generated value. This value is placed both in the session and the hidden field. The name of the session attribute is SESSION_CSRF_TOKEN
When the form is submitted to the server, you check whether the value in the session (SESSION_CSRF_TOKEN) equals the value sent in the HTTP request parameter CSRF_TOKEN. If not, you show some kind of error message and you stop processing. If they are equal, proceed.
If the user opens a new tab or duplicates a tab, the server will re-render the page and a new CSRF_TOKEN will be generated. So the user will only be able to submit the form from the newly opened tab , and not from the original.
This solution offers an additional bonus: It protects from CSRF attacks.

How can I store state for an individual browser tab/window?

I'm developing a single page jQuery & Backbone.js web app. The backend is a JBoss 6 application server.
Until now we had the following structure:
There is only one servlet (front controller). Every request from the JavaScript client goes through here.
In the servlet - at the first request of a certain JS client - I make a look p to a stateful session bean. For the next requests of this client, I store the result of the look up in an HTTP session container. So every JS client has exactly one stateful session bean. This connection is kept by a session cookie.
Now I have an additional requirement:
When the user has two browser tabs (in one browser), they should have two isolated instances of the web app in every browser tab. Because of that I have a problem with session cookies because this session cookie is for all browser tabs.
I have to change the structure so that:
The servlet has to generate a new session ID for the first request of a certain JS client. This session ID is communicated to the client.
With every POST to the backend the JS client has to send this session ID.
My question is:
Until now I saved the result of the look up in an HTTP Session object and I hadn't to think about generating a session ID. But now I have to store this somewhere else, where?
Has anybody experience with this kind of setting and can help me?
Update:
Thank you BalusC for this very interesting approach.
When I understood you well, this means:
All individual JS clients of the tabs of one browser share one HTTP session object. And in this HTTP session object, every tab has its own entry point. That sounds really good. So I still can use the whole HTTP session infrastructure and don't have to reinvent the wheel.
Autogenerate an unique value on the initial GET request which you store and pass around on every subsequent postback as a hidden input value. Use this unique value as identifier of the session attribute representing the view-scoped data.
During the 1st request on a brand new session, do:
Map<String, ViewData> viewScope = new HashMap<String, ViewData>();
session.setAttribute("viewScope", viewScope);
(the ViewData represents the view-specific data you'd like to track across postbacks on the same view)
During every GET request, do:
String viewDataId = UUID.randomUUID().toString();
viewScope.put(viewDataId, new ViewData());
request.setAttribute("viewDataId", viewDataId);
During generating the HTML, do:
<input type="hidden" name="viewDataId" value="${viewDataId}" />
During every POST request, do:
ViewData viewData = viewScope.get(request.getParameter("viewDataId"));
// Get/set view-specific data in there.
Make sure that jQuery also passes this hidden input around (which shouldn't be a big problem if you already properly use $(form).serialize() or e.g. AjaxForm plugin to ajaxify the forms).
If you're familiar with Java EE's MVC framework JSF, then it may be useful to know that its #ViewScoped annotation works roughly the same as described above. See also a.o. How to choose the right bean scope?
You can use session tracking with URL rewriting. See here:
Session shared in between tabs

Flex session parameters in Remote Object BlazeDS

I have my flex object embedded to JSP page.The JSP page retrieves user information like user name and group from portal profile object and stores in http session parameters. The flex Object makes a remote call to Employee.class to perform persona based operation.
I retrieved the session id in JSP and also in the Employee.class both are same. But I am not able to retrieve the username stored in the http session from FlexSession. I read in the internet that the FelxSession will hold all httpSession information as well. It’s always coming as null. Correct me if I am wrong.
In the JSP I set the
session.setAttribute("sasUserName","sasdemo");
session.setAttribute("sasGroupList",gl);
In Employee.class
import flex.messaging.FlexSession;
import flex.messaging.FlexContext;
mySession = (FlexSession)FlexContext.getFlexSession();
mySession.getAttribute("sasUserName")
Let me know if I need to make any other set up.
FlexContext should be called only inside of a blazeds AMF request - otherwise all the content is null. What happens is:
a)an AMF call is invoked
b)the MesageBroker servlet will setup the FlexContext object
c)the invoked method is executed
d)the MessageBroker servlet will clear the FlexContext object
e)the result of the call is returned.
Let me know if it's clear enough.

Wicket auth-role : inject external user credential from JSP

I am doing an incremental JSP --> Wicket migration. I had kept the JSP appliation and doing page by page migration. I gan go and return from JSP <--> wicket pages.But my problem is in JSP my logged in user credentials are stored in a Bean (UserBean,scope:session) and in JSP on each page I check logged in user from that bean.
But how can I get these informations in wicket? so that from my JSP page if a User is logged in, on wicket page load it can read that and set suer info so that my wicket log in page does not come.
my wicket page uses wicket-auth-role and checks with:
#AuthorizeInstantiation("ADMIN") public class HomePage extends BasePage {.....}
I have my own UserDetailsServcice and MyAuthenticationWebSession in wicket.
After some attempts and help from Don Roby, here I got userID from session in wicket:
final RequestCycle requestCycle = RequestCycle.get();
WebRequest wr=(WebRequest)requestCycle.getRequest();
HttpServletRequest hsr= wr.getHttpServletRequest();
AuthenticatedWebSession session = OrbitWebSession.get();
String username = (String)hsr.getSession().getAttribute("SessionUser");
Now,exactly where can I set username,password and call authenticate so that my page does not redirects to login page? Who calls authenticate() methods and how? I have tried onBeforeRender() method on my secured page,but it does not work. :(
More code specifically around the login process might help us make a more complete answer, but basically you have to get access to the normal servlet container session and thus to that bean from somewhere in wicket. Likely the best place to put that logic is somewhere in your MyAuthenticationWebSession, so that it knows the user is logged in.
To get at the servlet container session from wicket code, you can use
httpSession =
((WebRequest)request).getHttpServletRequest().getSession();
If at the point you're putting this in your wicket code you don't already have this WebRequest object (which is likely a ServletWebRequest object), you can get it from the RequestCycle:
RequestCycle requestCycle = RequestCycle.get();
Request request = requestCycle.getRequest();
authenticate is called by AuthenticatedWebSession during the login process. Unfortunately for you, most methods in the aforementioned class are marked final so it's a bit hard to customize.
What I think you should be able to do is to use the protected method signIn(boolean value) in the constructor of your own session. You get a Request there, from that you should hopefully be able to get your "SessionUser", then extract your User via your UserDetailsService, call signIn(true) and initialize the correct roles for that user. If signIn(true) is called, you shouldn't get a redirect to login.

Spring Session Management

I'm using Spring for my web app. I have used several SimpleFormControllers. I've created a session in the first SimpleFormController for the login page using:
HttpSession session = request.getSession(true);
How can I protect other SimpleFormControllers using Sessions, i.e. so that other controllers won't load if the user is not loged in.
Thank you
You probably want to use Spring Security.
It's flexible and allows restrictions based on roles.
Without it, you will need to manually check in every controller whether the user logged in or not. Or you'll have to "reinvent" a security framework by adding filter to the webapp.
If you only want to protect the operation of getting the session, you need to write a filter that wraps the original request and overrides the getSession methods. There you can check for login data using the original request's getSession().
BTW, getSession() is equivalent to getSession(true)
To protect the Controller from access outside of the intended Session, you may want to compare the Scoping rules you need with this clearly written Guide.
How to get Session Object In Spring MVC
The author gives an example of creating a Controller annotated with #Scope("session")

Categories