How to generate new session id with out extends HttpServlet class. Is it mandatory to extend HttpServlet class & Is it mandatory to genarate new session id with in doGet method
public class LoginSupport extends ActionSupport {
public void prepare() {
HttpSession session = ServletActionContext.getRequest().getSession();
session.invalidate();
//How to genarate new session id
}
}
After calling HttpSession#invalidate(), you can create a new session by calling HttpServletRequest#getSession().
For example
public void prepare() {
final HttpServletRequest request = ServletActionContext.getRequest();
request.getSession().invalidate();
// generate new session (and id)
final HttpSession newSession = request.getSession();
}
The next HTTP response from your server should include a new session ID, eg
Set-Cookie: JSESSIONID=6a303082951311647336934;path=/
From https://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpServletRequest.html#getSession--
getSession
HttpSession getSession()
Returns the current session associated with this request, or if the request does not have a session, creates one.
When on Servlet 3.1 or newer (Java EE 7), just use HttpServletRequest#changeSessionId().
request.changeSessionId();
It won't invalidate the session but just change the value of the JSESSIONID cookie.
Related
I have a Spring-boot back end and wish to save my user's session upon login in order to re-use his information further down the line.
This is how I try to do it so far:
#RequestMapping(method = RequestMethod.POST, value="/login")
public ResponseEntity<UserInfoMessage> loginUser(#RequestBody UserInfoMessage userInfoMessage, HttpServletRequest request) {
UserInfoMessage user = mapper.map(userService.login(mapper.map(userInfoMessage)));
// If our login was a success
if (user != null) {
// Save user session
HttpSession session = request.getSession();
session.setAttribute("user", user);
return new ResponseEntity<>(mapper.map(userService.login(mapper.map(userInfoMessage))), HttpStatus.OK);
} else {
return new ResponseEntity<>(mapper.map(userService.login(mapper.map(userInfoMessage))), HttpStatus.UNAUTHORIZED);
}
}
Where UserInfoMessage is a model that stores info such as my user's e-mail, name etc.
Here a session.getAttribute("user"); is working.
But when I try to retrieve it in another controller it is null:
#RequestMapping(method = RequestMethod.POST)
public ProjectInfoMessage createProject(#RequestBody ProjectInfoMessage projectInfoMessage, HttpServletRequest request) {
HttpSession session = request.getSession();
System.out.println("User is: " + session.getAttribute("user")); // null
return mapper.map(projectService.createProject(mapper.map(projectInfoMessage), (UserInfoMessage)session.getAttribute("user")));
}
What am I not understanding in session handling?
I have a MVC Web Api project and am logging all requests and responses using a MessageHandler. When an api request comes in, the bearer token in the header lets Asp.Net do its thing and authenticates that user. The message handler therefore knows who the user is and we write that to a log file.
Now, to speed up things I'm caching with Cachecow. So I've added the cachecow handler after the MessageHandler and when a second request comes in, from a caching point of view everything works fine. The controller code is never hit and the response is returned from the cache.
However, the MessageHandler does not have a value for the User.Identity so I cannot tell who made the request.
I need to log all requests and identify who made them even when the code in the controllers is not hit.
I think one workaround is to force the api requests to pass the bearer token and user id in the header. That way I can check the user id claim and use that to log who made the request.
protected override async Task OutgoingMessageAsync(string correlationId, string requestInfo, byte[] message, string responseTimeMilliseconds)
{
await Task.Run(() =>
Debug.WriteLine(string.Format("{0} - Response: {1}\r\n{2}", correlationId, requestInfo, Encoding.UTF8.GetString(message))));
);
}
User identity is null when getting response from cache.
?HttpContext.Current.User.Identity
{System.Security.Claims.ClaimsIdentity}
[System.Security.Claims.ClaimsIdentity]: {System.Security.Claims.ClaimsIdentity}
AuthenticationType: null
IsAuthenticated: false
Name: null
Any ideas?
In authentication process, set object:
System.Threading.Thread.CurrentPrincipal = YourUserInformationObject;
This object need implement "System.Security.Principal.IPrincipal" Example
public class YourUserInformation : IPrincipal
{
public Int32 Id { get; set; }
public String NameUser { get; set; }
public IIdentity Identity { get; private set; }
public YourUserInformation()
{
this.Identity = new GenericIdentity(NameUser ?? "");
}
public bool IsInRole(string role) { return false; }
}
In authentication process you save object in System.Threading.Thread.CurrentPrincipal
public void Authentication(AuthorizationContext filterContext)
{
YourUserInformation user = YourMethodGetUserLogin();
System.Threading.Thread.CurrentPrincipal = user ;
}
Well you should create HttpContext from Request and there you will be able to use User.Identity object:
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var context = ((HttpContextBase)request.Properties["MS_HttpContext"]);
var uname = username = context.User.Identity.Name;
var response = await base.SendAsync(request, cancellationToken);
return response;
}
Also check this article: http://arcware.net/logging-web-api-requests/
Hoope this help!
try get in
System.Threading.Thread.CurrentPrincipal
When we communicate with a servlet to applet how can we ensure that session information is preserved?
That is, how can we manage cookies in applet servlet connection?
You can use an API like org.apache.httpcomponents:httpclient https://hc.apache.org and use the HttpClient's CookieStore to set cookies to the request and read them from the reponse. Afterward you have to store the Cookie somewhere in your applet (see getSessionCookie() and setSessionCookie() method stubs):
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.*;
import org.apache.http.client.methods.HttpGet;
public class Connector {
private Cookie getSessionCookie() { /* TODO get cookie from some store (local session, DB, whatever) */ }
private void setSessionCookie(Cookie sessionCookie) { /* TODO set cookie to some store (local session, DB, whatever) */ }
private void connect() {
DefaultHttpClient client = new DefaultHttpClient();
Cookie sessionCookie = getSessionCookie();
if (sessionCookie != null) {
client.getCookieStore().addCookie(jsessionidCookie);
}
client.setRedirectStrategy(new DefaultRedirectStrategy());
// create a GET request to your Servlet in get()
HttpGet get = new HttpGet("http://example.com/your/servlet");
HttpResponse response = client.execute(method);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 200) {
sessionCookie = getJsessionidCookie(client.getCookieStore().getCookies());
// update session cookie
setSessionCookie(sessionCookie);
}
}
private Cookie getJsessionidCookie(List<Cookie> cookies) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals("JSESSIONID")) {
return cookie;
}
}
return null;
}
}
I wrote a simple servlet, in the doPost I got the user name and the password from a jspand authenticated the user by sending the password entered by the user to the data base(mysql). I got the data correctly and I am redirecting the user to another jsp page called welcome.jsp.
my question is , I wrote this method public String getUser(){return userNmae;}; I put it outside of the dopost method, however it is returning null. I have declared the variable userNmae as a class variable and when I debug , the variable contains a value in the dopost method , but it is null outside of the dopost method.why it is null outside of the dopost method?
I am calling getUser() method in the welcome.jsp page.
here is my code
public class UIclass extends HttpServlet {
public UIclass() { };
private String passWord = null;
private String userNmae = null;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name = request.getParameter("userName");
String password = request.getParameter("password");
Connection connection = null;
try {
connection = Connections.getConnection();
java.sql.PreparedStatement statement = connection.prepareStatement("SELECT PASSWORD,USERNAME FROM LOGIN where username =?");
statement.setString(1, name);
ResultSet resultset = statement.executeQuery();
while (resultset.next()) {
passWord = resultset.getString("PASSWORD");
userNmae = resultset.getString("USERNAME");
}
} catch (Exception e) {
// TODO: handle exception
} finally {
if (connection != null)
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
};
}
if (passWord.equalsIgnoreCase(password)) {
RequestDispatcher rd = request.getRequestDispatcher("welcome.jsp");
rd.forward(request, response);
}
}
public String getUser() {
return userNmae;
}
}
I'll answer by giving you a simpler example of what your code is actually doing:
Bottle bottle1 = new Bottle();
bottle1.setMessage("Hi there");
Bottle bottle2 = new Bottle();
System.out.println(bottle2.getMessage());
What would you expect this program to display? I would expect null, because you set a message on bottle1, and read the message from bottle2. These are two different bottles. When you put a message in a bottle, the message is in that bottle, not in the other bottles.
Your code does the same thing.
The servlet container creates an instance (unique) of UIclass. This is equivalent to creating the first bottle in my example.
The servlet is invoked when you send an HTTP request. It sets the user attribute in the servlet. This is equivalent to bottle1.setMessage("Hi there") in my example.
The container executes your JSP, which contains the code
<jsp:useBean id="uiclass" class="com.servlet.UIclass" scope="request">
This creates a new UIClass instance. It is equivalent to creating the second bottle in my example.
The JSP calls uiclass.getUser(). This is equivalent to getting the message from the second bottle in my example.
There are many, many things wrong in your code:
You shouldn't use scriptlets, and jsp:useBean tags
You should never create instances of servlets by yourself. A servlet is meant to be instanciated and called by the container.
You should realize that a unique servlet instance is called to serve, concurrently, all the requests of all the users to this servlet URL. Storing user-specific data in servlet attributes is thus really wrong
You probably want the user name to be available for all the subsequent requests of this user. That's what the HTTP session is for. You should store the user as an attribute of the HTTP session: request.getSession().setAttribute("userName", userName)
The JSP should use the JSP EL and the JSTL to access beans stored in the request or the session by the servlet:
<c:out value="${userName}"/>
I am trying to implement a simple servlet which uses a HTTP session in
an embedded jetty (7.3.0 v20110203) container. To start jetty I use the following code:
Server server = new Server(12043);
ServletContextHandler handler = new
ServletContextHandler(ServletContextHandler.SESSIONS);
handler.setContextPath("/");
server.setHandler(handler);
ServletHolder holder = new ServletHolder(new BaseServlet());
handler.addServlet(holder, "/*");
server.start();
server.join();
The servlet acquires a session with
HttpSession session = request.getSession(true);
and stores some data in it. Upon the next request it gets the session
with the following code:
HttpSession session = request.getSession(false);
and there the session is always null.
I did not find any information on
the internet about this particular problem. I have also experimented
with setting a SessionManager or SessionIdManager, but that did not seem
to change anything. I suspect I am missing something about SessionManager or SessionIdManager or SessionHandler here, but this is just a wild guess.
Your code works fine with this skeletal implementation of BaseServlet:
public class BaseServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
boolean create = "true".equals(req.getParameter("create"));
HttpSession session = req.getSession(create);
if (create) {
session.setAttribute("created", new Date());
}
PrintWriter pw = new PrintWriter(resp.getOutputStream());
pw.println("Create = " + create);
if (session == null) {
pw.println("no session");
} else {
pw.println("Session = " + session.getId());
pw.println("Created = " + session.getAttribute("created"));
}
pw.flush();
}
so the session is probably being invalidated somewhere else in your code.
The SessionHandler can also be explicity set using the setSessionHandler() method of ServletContextHandler.
//You need to setup SessionManager first. This worked for me.
Server server = new Server(8031);
ServletHandler handler = new ServletHandler();
server.setHandler(handler);
HashSessionIdManager hashSessionIdManager = new
HashSessionIdManager();
SessionHandler sessionHandler = new SessionHandler();
SessionManager sessionManager = new HashSessionManager();
sessionManager.setSessionIdManager(hashSessionIdManager);
sessionHandler.setSessionManager(sessionManager);
sessionHandler.setHandler(handler);
sessionHandler.setServer(server);
server.setSessionIdManager(hashSessionIdManager);
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
context.addServlet("webservlet.IndexServlet", "/index");
context.addServlet("webservlet.HomeServlet", "/home");
context.addServlet("webservlet.CategoryServlet", "/category");
context.addServlet("webservlet.ProductServlet", "/product");
...
The method HttpServletResponse#reset() destroys a newly created session, so a new one is created the next time and so on.