HttpSession invalidate is redirecting to login page - servlets

Hi I'm using servlet filter to change session ID on every request in order to avoid session fixation. My problem is when the method doFilter ends the application is redirected to login page. I just want to invalidate and create new session, without redirect. I don't have any other filter.
There is my doFilter code:
HttpSession session= httpServletReq.getSession();
if(session!=null){
User u = session.getAttribute("user");
session.invalidate();
HttpSession newSession = httpServletReq.getSession(true);
newSession.setAttribute("user", u);
}
chain.doFilter(req, resp);
The pattern on filter is ***.xhtml**
Why am I getting redirect to login?
Is it ok to change session ID on a filter?
Thanks

change session ID on every request in order to avoid session fixation
You should do exactly that instead of invalidating the session. You can use HttpServletRequest#changeSessionId() for this.
HttpSession session = httpRequest.getSession(false);
if (session != null) {
httpRequest.changeSessionId();
}
chain.doFilter(request, response);
Do note that HttpServletRequest#getSession() defaults to auto-creating the session, so it actually never returns null. You need to explicitly pass false to HttpServletRequest#getSession(boolean).
That said, you don't necessarily need to perform this on every request, it's sufficient to perform that only at the moment when you login the user.

You only need method session.invalidate().
When you call 'session.invalidate()`, the existing session will be invalidated.
so the servlet request will create new session to network.

Related

How does session managment work in spring?

I can't really understand the concept of this.
Take a look what I have:
#PostMapping("/login")
public ModelAndView login( #ModelAttribute UserLoginDTO userDto, HttpSession session) {
if (authenticateService.loginCheck(userDto.getUsername(), userDto.getPassword())) {
session.setAttribute("sessionid",123);
return new ModelAndView("redirect:/profile");
} else {
return new ModelAndView("signin","error","Invalid username or password combination, or the user does not exist.");
}
}
I have set a sessionID to the session. When the user navigates around the website, how do I know that it is the same user?
Do I have to store the sessionID on server side in a ConcurrentHashMap?
And when there is a page switch I should do this?
if (conHashMap[...] == session.getId()) {...}
else //redirect to login page
Also on logout, do I just remove the element from the hashmap and call for session.invalidate()?
Or is there a way of doing this without using hashmaps at all?
You know the session is from the same user if the id is the same, yes.
You can eventually store informations on the session. Alternativelly, you can create session scoped beans :
#Component
#Scope(value="session")
public class MyComponent {
// ...
}
All you will store in this kind of objects are only accessible by one user.
Figured it out.
After invalidating, the browser will visit the site with a new session. The new session won't have the "sessionid" attribute bound to it. This way, I could determine which session is a valid one, without using hashmaps.
if (session.getAttribute("sessionid")==null){
return new ModelAndView("signin","error","Session expired, please log in again.");

RequestDispatcher to a jsp or servlet

Parameters[userName, UserPW] are sent by the user through a home.jsp. These parameters are matched in Login servlet against a stored userInfo Db using JDBC.
In the doPost method I am using if condition tfor authentication as follows
if (rs.next()) {
String refName = rs.getString("UserName");
String refPass = rs.getString("userPW");
if (user.equals(refName) && pw.equals(refPass)) {
out.println("<br>You are In");
RequestDispatcher dispatch= getRequestDispatcher("/SearchFriend.jsp");
dispatch.forward(req, resp);
System.out.println("sucess");
}
When the authentication is successfull, How can i direct the user to a new jsp or servlet where he can input few textboxes and select-options to select few records from the Db table.
its not clear to me that How can I direct the page to a Search.jsp page in above If condition. The Search.jsp is in weBContent folder of Juno.
I am using JDBC with tomcat7. Please help
It is probably not clear , what exactly your requirement are and what you are trying to achieve by looking into the code you have posted.Kindly reframe your question
According to my assumption , you need to redirect the user to the home page when the authentication is successful.
If so, for that you can store the user credential in the session by making a custom filter say SessionFilter implements Filter
HttpSession session = request.getSession();
Store the credenials in the session and if authentication is successful then redirect using :
RequestDispatcher view = request.getRequestDispatcher(/home.jsp);
view.forward(req,resp);

Redirect to last visited page (stored in a cookie)

In our MVC application we want the user, after he is logged in, to be redirected to the page he visted last in a previous session.
What is a good approach for achieving this?
I am thinking of an httpmodule-->begin request or via the global.asax
And at which point in the requestprocess should I put the logic to check whether the cookie exists and do the redirect? In the Application.init?
Any advice would be really appreciated!
You could create a custom action filter that saves the currently requested URL to the cookie. Then check for the cookie value in your login action method and redirect if necessary.
In doing this you could decorate only the controllers and actions that you want that are potential entry points. e.g. not actions that return partial views etc.
That is correct, there is no event on click. However, there is a much simpler soluction, MVC handles form submits and redirects quite well. To store the last visited URL, you could use an action filter on your controller. Then to handle the redirect, create two Login functions. One handles the GET request, the other the POST request. In the POST request, after having verified authentication, retrieve the URL (or action) from the cookie and redirect the user.
It would be something like this:
[HttpGet]
public ActionResult Login()
{
return View();
}
[HttpPost]
public ActionResult Login(LoginViewModel model)
{
if (authenticated)
{
//get cookie information
HttpCookie cookie;
cookie = Request.Cookies["StoredURLFromLastSession"];
String StoredURLFromLastSession = cookie.Value;
//Choose one of these redirect methods
//returns to a hard coded URL
//return Redirect(StoredURLFromLastSession);
//redirects to a route (using routes created in global.asax
//return RedirectToRoute(StoredURLFromLastSession);
//redirects to a specific action/controller
//return RedirectToAction(StoredURLFromLastSession);
}
}
Hope this helps.

storing user ID in session

When the user logs in, I want to store his userID in the session with
HttpContext.Current.Session["UserID"] = 2354; (this is just a hard-coded example)
Then, when I run a page method, if I do
var test = HttpContext.Current.Session["UserID"];
will the variable test hold the value I stored when he logged in?
If this is a correct way of doing it, how do I access the session when I receive a call from a page method? I want to put the test =... line in a page method to identify which user the request is coming from.
Thanks.
As has been already answered, yes - it should be fine, though if you sit on a page too long before calling a service using this method [WebMethod] it will fail. Best practice in that case is to check for the session and rebuild as necessary. The same is true for any other authentication to ensure that they haven't become unsyncronized or expired.
[WebMethod(EnableSession = true)]
HttpContext context = HttpContext.Current;
if (context.Session["UserID"] == null) {
Utilites.PopulateSessionVars(context.Request.ClientCertificate, context.Request.ServerVariables["REMOTE_ADDR"]);
}
String userId = context.Session["UserID"].ToString();
(where Utilities.PopulateSessionVars is a method to rebuild the session data off of whatever you're using to log in ... which in my case is a PKI certificate)
Yes, that should work. However, session and forms authentication timeouts are on different timers and have different default timeouts so you cannot guarantee that value in session will be available for the time period during which the user is authenticated if you are using forms authentication.
This should do it
//Note: this code hasn't been tested. Correct me if I'm wrong
//To Set:
if (Session["UserId"] == null)
Session["UserId"] = "12345";
//To Get it:
if (Session["UserId"] != null)
MyObject.Id = Session["UsedId"].ToString();
Yes, but its advisable to do a test straight after your test variable assignment to make sure that the UserID was set correctly before you try to use it.
EDIT
You could try:
var test;
if (HttpContext.Current.Session["UserID"] != null)
{
test = HttpContext.Current.Session["UserID"];
}
Global.asax runs at the application level. You want the user sessions which is a differet http context. Initialize the Session in the home/default login page instead.

Java Servlet session management, how to create session for login

I am working on a small webapp for fun, using just Java Servlets at the moment. I have two pages, test1 and test2. At the moment I am creating a new session in test1 like this:
HttpSession session = request.getSession(true);
if (session.isNew() == false) {
session.invalidate();
session = request.getSession (true);
}
In test2 I am retrieving the session like so:
HttpSession session = request.getSession(false);
if (session == null) {
throw new ServletException ("No session.");
}
So the problem is that if I go to test2 first, I am always getting a valid session because the browser creates one. I want to restrict the flow from test1 to test2 so that I have to go to test1 first. My plan is to eventually create a login page that will create the session, but the problem I am seeing here would still be present.
How should I handle this? I would like any ideas to not include 3rd party libraries. I'm doing this as a learning exercise.
Thanks!
This makes no sense. Forget the request.getSession(boolean). Just get the session by request.getSession() and never worry about the nullness/validness.
If you want to pass data through session attributes, then just do in test1:
request.getSession().setAttribute("test", "foo");
and in test2 (which is of course requested in the same session after test1):
String test = (String) request.getSession().getAttribute("test"); // Returns "foo".
As to using the session to check the logged-in User, just do something like in the login code:
User user = userDAO.find(username, password);
if (user != null) {
request.getSession().setAttribute("user", user);
} else {
// Show error?
}
and then in a Filter which is mapped on a url-pattern which represents the restricted area, just check if the User is present or not:
if (((HttpServletRequest) request).getSession().getAttribute("user") != null) {
chain.doFilter(request, response); // Just continue.
} else {
((HttpServletResponse) response).sendRedirect("login"); // Not logged-in, redirect to login page.
}
and when you logout, you just remove the User from the session:
request.getSession().removeAttribute("user");
// Or, more drastically:
request.getSession().invalidate();
Alternatively you can also take a look for declarative Container Managed Security with help of some simple entries in web.xml and the server.xml. This way you don't need to hassle with login/filter logic yourself.
See also:
How do servlets work? Instantiation, sessions, shared variables and multithreading
How to handle authentication/authorization with users in a database?
Authentication filter and servlet for login
If you want to restrict the flow to ensure that test1 comes before test2, have test1 put an attribute value in the session that says it's been visited, and test for that attribute value in test2. If the value is not there, have test2 redirect to test1.
In test1, do this:
HttpSession session = request.getSession();
session.setAttribute("test1",true);
Then, in test2, you can do this:
HttpSession session = request.getSession();
if (session.getAttribute("test1") == null){
response.sendRedirect("test1");
return;
}
A session is just a basket that starts out empty. The concept of whether a user is authenticated or not is separate from whether or not the user has a session.
Java EE and the servlet specifications handle all the login stuff for you, redirecting to login pages and so on. Read up on the built-in capabilities of Java EE. Maybe start here.
When someone login with right credentials set a secession with this
request.getSession().setAttribute("user", "user");
now, you can check in this session user already present or not with this
if (((HttpServletRequest) request).getSession().getAttribute("user") != null)
and you can delete the session at the time of logout
request.getSession().invalidate();
this work perfectly
NOTE:
import HttpServletRequest and pass request parameter like this
import javax.servlet.http.HttpServletRequest;
public home(HttpServletRequest request){}

Resources