I am creating a session in one of the servlets of my web application using HttpServletRequest.getSession(true) which also creates a cookie JSESSIONID. I want to change the path associated with this cookie. I am trying to do this by setPath method but its not working. I am using tomcat6. Thanks in advance. Below is the code I am using
HttpSession session = httpRequest.getSession(true);
Cookie[] cookies = httpRequest.getCookies();
if(cookies != null) {
for (Cookie c : cookies)
{
if(c.getName().equals("JSESSIONID"))
{
c.setPath("somepath");
}
}
}
You have changed the cookie path but did not attached the modified cookie to the response. So on the client side, the change is never going to be recognized.
Add the modified cookie to the response like this httpResponse.addCookie(c) after modifying it.
Try this code:
HttpSession session = httpRequest.getSession(true);
Cookie[] cookies = httpRequest.getCookies();
if(cookies != null) {
for (Cookie c : cookies)
{
if(c.getName().equals("JSESSIONID"))
{
c.setPath("somepath");
httpResponse.addCookie(c);
}
}
}
However it will not delete the existing cookie which has the old path instead it will create a new cookie with new path.
Unfortunately i could not able to find a way to delete the existing cookie. I have tried to remove the old cookie by setting it maxAge to -1 but didn't worked. Here is the code that i've tried so far:
String jSessionId = null;
HttpSession session = request.getSession(false);
if(session == null) {
session = request.getSession(true);
}
Cookie[] cookies = request.getCookies();
if(cookies != null) {
for (Cookie c : cookies)
{
if(c.getName().equals("JSESSIONID"))
{
jSessionId = c.getValue();
c.setValue(null);
c.setMaxAge(0);
response.addCookie(c);
}
}
}
if(jSessionId != null) {
Cookie c = new Cookie("JSESSIONID", jSessionId);
c.setPath("/servlet/sayhello");
c.setHttpOnly(true);
response.addCookie(c);
}
There is no major issues by having 2 different cookies. So you can use the first code snippet if you are comfortable with having two cookies.
Related
What is the Java Equivalent for HttpContext in C#? I need to convert the following to Java. This code is basically extracting a cookie.
// This method returns the username from the login cookie, or null if no user is logged in.
public string ExtractUser(HttpContext context)
{
// Get the correct cookie from the request
var Cookie = context.Request.Cookies["dummyUser"];
// Return the cookie's value if it exists
if ((Cookie != null) && (Cookie.Value != null))
return Cookie.Value;
// Return null otherwise
return null;
}
Code base from here: https://sisense.dev/guides/sso/jwt/#actions
Try HttpServletRequest
See Here getCookies() method
public static String getCookie(HttpServletRequest req,String name) {
Cookie[] cookies = req.getCookies();
if(cookies!=null) {
for (Cookie cookie : cookies) {
if(cookie.getName().equals(name)) {
return cookie.getValue();
}
}
}
return null;
}
Currently setting up http only cookie in a Spring boot project via configurations as follows.
This cookie is getting set correctly when ever I call following endpoint.
#Bean
public CookieSerializer defaultCookieSerializer() {
DefaultCookieSerializer cookie = new DefaultCookieSerializer();
cookie.setDomainNamePattern(".*");
cookie.setCookieName("my_cookie");
cookie.setUseSecureCookie(true);
cookie.setUseHttpOnlyCookie(true);
cookie.setCookieMaxAge(1200);
return cookie;
}
As can see, the cookie called my_cookie is being set for 2 mins.
In my controller within same project, I have the following controller method.
In the event I enter the error block, I wish to delete the cookie called my_cookie. How can I do that?
This is the closest question I found for this but is not the same case considering I set it via configurations.
https://stackoverflow.com/questions/9821919/delete-cookie-from-a-servlet-response
#PostMapping(value = "/endpoint")
public List CustomResponse(
#RequestBody Request request,
) throws Exception {
CustomResponse response = null;
if (otherCookie != null) {
CustomResponse response = // perform some other rest request and get value from there
}
if (response == null) {
// I want to delete the cookie named `my_cookie` at this stage.
throw new CustomException('name');
}
return response;
}
To delete a cookie, set the Max-Age directive to 0 and unset its value. You must also pass the same other cookie properties you used to set it. Don't set the Max-Age directive value to -1. Otherwise, it will be treated as a session cookie by the browser.
// create a cookie
Cookie cookie = new Cookie("username", null);
cookie.setMaxAge(0);
cookie.setSecure(true);
cookie.setHttpOnly(true);
cookie.setPath("/");
//add cookie to response
response.addCookie(cookie);
For more, refer to the post by Dzone:
https://dzone.com/articles/how-to-use-cookies-in-spring-boot
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 am new in jsp. I am trying to do redirection to login page when expire the session.
My code:
String sessionUser = null;
sessionUser = session.getAttribute("UserName").toString();
if(sessionUser == "" || sessionUser == null)
{
System.out.println("In login");
response.sendRedirect("login.jsp");
}
else
{
System.out.println("out login");
}
in above code i get error in line of
sessionUser = session.getAttribute("UserName").toString();
Error
HTTP Status 500 - An exception occurred processing JSP page
How can i do this?
From the error message and your description it seems you have written this code in JSP :
sessionUser = session.getAttribute("UserName").toString();
The above line can throw error if session is null or session doesn't have a UserName attribute .It is bad practice to write scriptlets in JSP.
You need to use a Filter to do anything closer to what you intend to do :
// Do not create session if it doesn't exist
HttpSession session = request.getSession(false);
// check if session is null
if(session != null) {
chain.doFilter(request, response);
} else {
// redirect to login page
response.sendRedirect("/login.jsp");
}
You can implement HttpSessionListener to listen to the session invalidation event. But a Listener is not a good choice here , because it is not tied to a request.
I need to get current session Id without hitting the session (to give it a chance to expire).
I've used Cookies from Servlet code in order keep the session not-touched and then make the session expires after its timeout time.
I am using the following code:
public static String getSessionId(HttpServletRequest request)
{
String sessionId = "";
String logMsg = "";
if (request != null)
{
String sessionTimeout = PropertiesReader.SESSION_TIMEOUT_SCHEMA;
if (sessionTimeout != null && SessionHelper.SESSION_TIMEOUT_FIXED.equalsIgnoreCase(sessionTimeout))
{
logMsg = "FIXED: Getting SessionId from Cookies with activating the session";
Cookie[] cookies = request.getCookies();
if (cookies != null)
{
for (Cookie cook : cookies)
{
if ("JSESSIONID".equalsIgnoreCase(cook.getName()))
{
sessionId = cook.getValue();
break;
}
}
}
} else
{
logMsg = "PER_USAGE: Getting SessionId from Session";
sessionId = request.getSession(false) != null ? request.getSession(false).getId() : "";
}
}else
{
logMsg = "Request object is null";
}
logger.info(logMsg + ", sessionId=" + sessionId);
return sessionId;
}
One one OC4J app server, it works fine. although on another oc4j server, the code of accessing cookies makes the session keep active and don't timeout!
EDIT:
I really stucked!, I've trying to place afilter to remove the JSESSIONID cookie and remove all cookies from the HttpServletRequest, but when I call getSession(false) on the request passed to the servlet, I got a valid Session!
class CookieRemovalHttpServletRequestWrapper extends HttpServletRequestWrapper
{
public static final String COOKIE_HEADER = "cookie";
public static final String JSESSIONID = "JSESSIONID";
public CookieRemovalHttpServletRequestWrapper(HttpServletRequest request)
{
super(request);
}
#Override
public String getHeader(String name)
{
if (COOKIE_HEADER.equalsIgnoreCase(name))
{
return "";
}
return super.getHeader(name);
}
#Override
public Enumeration getHeaderNames()
{
Enumeration e = super.getHeaderNames();
List l = new ArrayList();
while (e.hasMoreElements())
{
String headerName = (String) e.nextElement();
if (!COOKIE_HEADER.equalsIgnoreCase(headerName))
{
l.add(headerName);
}
}
return Collections.enumeration(l);
}
#Override
public Enumeration getHeaders(String name)
{
if (COOKIE_HEADER.equalsIgnoreCase(name))
{
return new Enumeration()
{
public boolean hasMoreElements()
{
return false;
}
public Object nextElement()
{
return null;
}
};
}
return super.getHeaders(name);
}
#Override
public Cookie[] getCookies()
{
Cookie[] cs = super.getCookies();
List<Cookie> cokRet = new ArrayList<Cookie>(cs.length);
for (Cookie c : cs)
{
if (c.getName().equalsIgnoreCase(JSESSIONID)) continue;
cokRet.add(c);
}
return cokRet.toArray(new Cookie[] {});
}
}
And really think to forget all about Session and just use the session Id as just a unique identifier to the user, and do it myself the hard way.
As to your code, don't do it the hard way, use HttpServletRequest#getRequestedSessionId() and HttpServletRequest#isRequestedSessionIdValid() instead to check the requested session ID and if it is valid.
if (request.getRequestedSessionId() != null && !request.isRequestedSessionIdValid()) {
// The session has been expired (or a hacker supplied a fake cookie).
}
As to your concrete problem:
the code of accessing cookies makes the session keep active and don't timeout!
No, the code doesn't do that. It's the HTTP request itself which does that. It is not true that whenever you don't call getSession() or something, the session timeout won't be postponed. It will be postponed on every single HTTP request fired by the client, regardless of whether you need the session in the code.
To learn about how sessions work, you may find this answer helpful: How do servlets work? Instantiation, sessions, shared variables and multithreading
The session expiring isn't dependent on your code accessing the session, it depends on the user making a request with that session. Every time the user makes a request, the session's timeout will reset itself.
If you want to not have the user's request re-set the timeout (ie. have a fixed-length session), then you will need to do additional things for configuring the session, including possibly using a different filter to handle sessions.
The session is not timeout, that is correct behavior, because request was accepted and session expiration is updated in any case.