I am very new to java servlet programming. I have been writing a simple program for practicing java session. There are two .jsp file. first one called index.jsp, and another one is selection.jsp. And there is a servlet called controller. At first the index.jsp will be called, and user will be submit a input. That will be redirect in servlet controller. In that servlet will check whether it is new request or not. If new then it redirect to other page, else will do some other work.
I am checking whether it is new request or not by session.isNew() method. But it always says it is not new session. But, if I disable the browser cookies option then it is working fine. Now what is my observation is that when in the first I request the index.jsp to the container it assign a session along with that request. So when it comes to servlet it treat as a old session. I got this idea from Head first book Servlet and JSP.
Here is my servlet code -
public class Controller extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String user;
HttpSession session = request.getSession(false);
if (session == null) {
user = request.getParameter("user");
if (user == null) {
response.sendRedirect("index.jsp");
}
session.setAttribute("username", user);
SelectItem selectItem = new SelectItem();
selectItem.setUser(user);
response.sendRedirect("selection.jsp");
session.setAttribute("selectItem", selectItem);
} else {
String selectionItem = request.getParameter("selection");
SelectItem selectItem = (SelectItem) session.getAttribute("selectItem");
if (selectItem != null) {
selectItem.add(selectionItem);
session.setAttribute("selectItem", selectItem);
}
response.sendRedirect("selection.jsp");
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
So, how to determine whether it is a new session or old one? Thank you.
HttpSession.isNew API:
Returns true if the client does not yet know about the session or if the client chooses not to join the session. For example, if the server used only cookie-based sessions, and the client had disabled the use of cookies, then a session would be new on each request.
So, you're getting true because the client has cookies disabled. The "new session" check in done in the else block of this check:
HttpSession session = request.getSession(false);
if (session == null) {
// create new session
session = request.getSession();
} else {
// existing session so don't create
}
In your code, you don't appear to be creating a new session when a new session is detected. Perhaps that's where you're stumbling.
Note: learning the basic Servlet API is a good thing. However, for my professional work I use frameworks which simplify my programming, like Spring Boot and Spring Security.
Related
I have been trying to find the reason as to why my session would be lost when I do a POST.
I am checking my session all throughout my app but the session will drop when I call a particular servlet and it only drops on this particular one. The issue is intermittent so it is very frustrating. I'm not sure what is needed so I'll put as much info as I can up.
The page is accessed through a servlet. I can verify that the session is still the same.
As the user is routing through the app, I can see that the session is still the same.
Checking Session:HTTP Session CEHKIIMEKHMH
Calling Get Details
Checking Session:HTTP Session CEHKIIMEKHMH
Calling Project Details
Checking Session:HTTP Session CEHKIIMEKHMH
Calling Attachment Controller
Checking Session:HTTP Session CEHKIIMEKHMH
public class Attachments extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("Calling Attachment Controller");
HttpSession session = request.getSession(false);
System.out.println("Checking Session:"+session);
if(session != null){
Object projectId = session.getAttribute("projectId");
request.getRequestDispatcher(response.encodeURL("views/attachments.jsp")).forward(request, response);
}else{
System.err.println("Invalid session");
response.sendRedirect("/");
}
}
}
Here is my form posting. The form is actually submitted via javascript after I perform validation, I just merely call $('#files).submit(); not sure if that really matters or not.
<form id="files" name="files" method="POST" action="FileUpload" enctype="multipart/form-data">
The moment they post, the session is lost
Calling File Upload
Checking Session:null
null
Here is the start of the servlet
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("Calling File Upload");
HttpSession session = request.getSession(false);
System.out.println("Checking Session:"+session);
if(session != null){
Object projectId = session.getAttribute("projectId");
System.out.println("Accessing File Upload: Session is valid");
It's the same method all across the board. I have no idea what the problem is.
I've narrowed down the issue but I still have not resolved it yet. It happens during my redirect. I also was not encoding the URL correctly. I have modified all my redirects to have the folowing:
request.getRequestDispatcher(response.encodeRedirectURL("views/attachments.jsp")).forward(request, response);
This only resolves it on the server side though and does not provide a solution when I am handling redirects from the client.
I ran the code in the debugger and confirmed that the object was being created in the Java code and was null in the JSP. Why is the JSP using a new session?
In debugger, it goes into Java code and sets the captcha in a session with an id. When I run the JSP, it gets the session with a different id, fails, then goes into doGet() and sets the current id session with a new captcha object. Storing captcha in a session, but that session isn't being used when the JSP runs.
Here are some code snippets
Java:
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ColoredEdgesWordRenderer wordRenderer = new ColoredEdgesWordRenderer(COLORS, FONTS);
Captcha captcha = new Captcha.Builder(_width, _height).
addText().addNoise().
addBackground(new BrightGradiatedBackgroundProducer()).
build();
CaptchaServletUtil.writeImage(resp, captcha.getImage());
req.getSession().setAttribute("simpleCaptcha", captcha); // object is getting set
}
JSP:
session=request.getSession(false);
if (session==null)
session=request.getSession(true);
boolean isCaptchaTrue = false;
String strCaptcha = request.getParameter("captcha");
String captchaType = request.getParameter("captchaType");
if (strCaptcha != null && captchaType != null) {
if(session.getAttribute("simpleCaptcha") instanceof Captcha){
Captcha captcha = (Captcha) session.getAttribute("simpleCaptcha");
isCaptchaTrue = captcha.isCorrect(strCaptcha);
}else if(session.getAttribute("simpleCaptcha") instanceof AudioCaptcha){
AudioCaptcha captcha = (AudioCaptcha) session.getAttribute("simpleCaptcha");
isCaptchaTrue = captcha.isCorrect(strCaptcha);
}
}
I found my problem. At the top of the JSP the session was being invalidated. I removed session.invalidate() and it works now.
Suppose I have a servlet that processes logins. When the login is successful the user will create a session for this user. Then redirects to a homepage.
Let's say the homepage has a link "view all". This link calls a servlet, viewall.html to process all the data from the database then redirect to a jsp page (viewall.jsp) that will display the data from the servlet.
Somewhere from the servlet viewall.html to the jsp viewall.jsp, I would like to have code that looks like this:
if (session attribute user is null) {
// redirect to the login page
} else {
// if in the servlet, retrieve the data from the database
// if in the jsp, display the data
}
What is the better way to check if there is a session, on the servlet or the jsp? Note I know about filters, let's say the project can't use filters.
It is the same using a servlet of a filter. The general way is :
in the servlet that processes login you
create a new session
Session old = request.getSession(false); // first invalidate old if it exists
if (old != null) {
session.invalidate();
}
Session session = request.getSession(true); // next create one
put the user id as attribute of the session
session.setAttribute("USERID", userId);
then in the element (filter of servlet) where you want to know whether you have a registered user :
Session = request.getSession(false);
if ((session == null) or (session.getAttribute("USERID") == null)) {
response.sendRedirect(homeUrl);
return; // no need to process further (if in a filter no need to go down the chain)
}
in the servlet after controlling you have a logged on user, forward to the jsp
request.getRequestDispacher("/path/to/displayer.jsp").forward(request, response);
That's all ...
If you want to check this before creating, then do so:
HttpSession session = request.getSession(false);
if (session == null) {
// Not created .
session = request.getSession();
} else {
// Already created.
}
If you don't care about checking this after creating, then you can also do so:
HttpSession session = request.getSession();
if (session.isNew()) {
// newly created.
} else {
// Already created.
}
<% if(session.getAttribute("sessionname")==null)
{
response.sendRedirect("index.jsp");
else
{
String activeUser=session.getAttribute("sessionname").toString();
}
I hope it helps you
I have a small spring MVC-app with session, with also some small amount of REST methods.
If I copy the JSESSIONID and use it with a 'curl'-command I'm able to access the rest methods from a different computer with a different IP, and thus 'faking' a session.
Is there a way to "bind" a session to one IP-address?
You can bind a session to IP address using a custom filter:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
boolean chainCompleted = implementEnforcement(request, response);
if (!chainCompleted) {
filterChain.doFilter(request, response);
}
}
private boolean implementEnforcement(HttpServletRequest request, HttpServletResponse response) throws IOException {
final String key = "enforcement.ip";
HttpSession session = request.getSession(false);
if (session != null) {
// we have a session
String ip = request.getRemoteAddr();
String ipInSession = session.getAttribute(key);
if (ipInSession == null) {
session.setAttribute(key, ip);
} else {
if (!ipInSession.equals(ip)) {
// JSESSIONID is the same, but IP has changed
// invalidate the session because there is a probability that it is
// a session hijack
session.invalidate();
return true;
}
}
}
return false;
}
It remembers user's IP address and then compares current IP with the remembered one: if it differs, the session is destroyed.
you can use Spring security hasIpAddress() check spring security refrence
You should read through Session Fixation Attack Protection in the Spring documentation, where it is written, that you can configure that inside the session-management tag
<session-mangagement session-fixation-protection="migrateSession|none|newSession">
migrateSession - creates a new session and copies the existing session attributes to the new session. This is the default.
none - Don't do anything. The original session will be retained.
newSession - Create a new "clean" session, without copying the existing session data.
a session will be fixed to a set of variables like browser agent, IP. So in your case the browser agent of curl will not match and the provided sessionid will be of no use
Suppose a person is logged in with user id and password in an app. Now with same user id and password he is trying to log without logging out from first session. I want to make it that it willlog out from and first session and continue with new one automatically.
Struts2, JSP , Java are technologies , i m using for my apps.
Problems facing
IE 8 giving same session id in same machine if we open in new tab or window. Not able to differentiate between different login from same machine.
How to set own session id?
Banking application like SBI sites and all works like that only , how does it work real time?
I want to replicate same thing like SBI bank sites work on online transaction. Send message session out in first window if you open again in new window
Please let me know how does this logging part in details.
Thanks.
This is my filter
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.out.println("FirstFilter : In filter doFilter before doFilter...");
HttpServletRequest req = (HttpServletRequest) request ;
HttpServletResponse res = (HttpServletResponse) response ;
HttpSession session = req.getSession(false);
String userId=req.getParameter("username");
String password=req.getParameter("password");
System.out.println(" : : " + req.getParameter("username")) ;
System.out.println(" : " + req.getServletPath());
LoggedInUserVO userProfVOSession = null ;
if(session != null) {
String sessionId=session.getId();
userProfVOSession = (LoggedInUserVO)session.getAttribute("LoggedInUser") ;
//check for login id password and session for single user sign in
if(null!=userProfVOSession){
if(userProfVOSession.getUserName().equalsIgnoreCase(userId) && userProfVOSession.getUserPassword().equals(password) && userProfVOSession.getSessionId().equals(sessionId)){
//do nothing
}
else{
System.out.println("in duplicate");
}
}
}
if(userProfVOSession == null) {
if("/populatelogin.action".equals(req.getServletPath()) || "/login.action".equals(req.getServletPath())||"/images/Twalk-Logo-4-green.png".equals (req.getServletPath())||"css/twalk.css".equals( req.getServletPath() )) {
chain.doFilter(req, res) ;
} else {
req.getRequestDispatcher("Entryindex.jsp").forward(req, res) ;
}
} else {
chain.doFilter(req, res) ;
}
Basically your requirement leads to web security vulnerability.If a person is already logged in, then his session must be active.Now the scenario is like this:
If you tries to login again with the same credentials, he wll be automatically logged in.
If you want to kill the old session for every login, then what you need to do is , you need to get a new session every time when you login, so your old session will be expired.You can achieve this by just writing a filter.In this filter check whether the user is already associated with a session or not, if yes, then invalidate his current session and start new one.This will solve the issue of multiple login attempts.
Remember that when a session is initiated, then the server is sending a cookie back to the user.Henceforth for every subsequent request made, this cookie will be transmitted to the server. Even if that if you open multiple tabs in browsers, this same cookie only is sent back to the server.
Hope I understood this.