Unable to Close my Session Servlets - java

I am unable to close my session using session.invalidate() in my logout method please help!
public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException
{
response.setContentType("text/html");
PrintWriter out = response.getWriter();
response.getWriter().println("<h3><a href='/assign2'>Logged out Successfully</a></h3>");
HttpSession session = request.getSession(false);
if(session!=null)
session.invalidate();
}
the username does not get written to null at all
here's my welcome page to where i am redirecting it
HttpSession session=request.getSession(false);
if(session!=null)
{
if((request.getSession().getServletContext().getAttribute("userid")) != null)
{
username = request.getSession().getServletContext().getAttribute("userid").toString();
}
}
System.out.println(username);

The logoff page is OK, but in the welcome page you are mixing concepts:
Altough the execution of session.invalidate does unbind all the bound attributes, you are retrieving attribute userid from the ServletContext, not the Session. Besides, note that request.getSession() creates a new session if necessary.
The coherent way to store and retrieve attributes would be through the HttpSession object:
HttpSession session=request.getSession(false);
if(session!=null)
{
if((session.getAttribute("userid")) != null)
{
username = session.getAttribute("userid").toString();
}
}
System.out.println(username);

Related

How to authenticate and create session programmatically in security context

Hi i have an application that uses its own implementation for user to authenticate ,by saving a User pojo in the HttpSession and invalidating that HttpSession Object when the session is done, but what i want to do is to use the security context to authenticate the user.
let's say that i have servlet AuthenticateUserServlet:
public void doPost(HttpServletRequest req,HttpServletResponse resp)
throws ServletException,IOException{
String username=req.getParameter("username");
String password=req.getParameter("password");
if(Authenticator.check(username,password)){
HttpSession session=req.getSession(true);
session.setAttribute("user",Authenticator.getUser(username));
PrintWriter out= req.getWriter();
out.println("<h2>Welcome</h2>");
}else{
PrintWriter out= req.getWriter();
out.println("<h2>the password or username are incorrect</h2>");
}
}
the code above won't give me the power of security context so what i wan't is when i check that the user is ok to login tell in someway the security context that this user can access here are his roles
something like this inside my AuthenticateUserServlet:
public void doPost(HttpServletRequest req,HttpServletResponse resp)
throws ServletException,IOException{
String username=req.getParameter("username");
String password=req.getParameter("password");
LoginContext lc = new LoginContext("my-jaas",new MyCallbackHandler(username,password));
try{
lc.login();
//notice i have not save any thing in the HTTPSeession
//i want my container to remember this user like what happens in the
// form based authentication where nothing gets saved in the httpSession
// but the user keeps logged in(cartalina uses a session object not httpsession for that)
PrintWriter out= req.getWriter();
out.println("<h2>Welcome</h2>");
}
catch(LoginException e ){
PrintWriter out= req.getWriter();
out.println(e.getMessage());
}
}
i have created my own LoginModule ("my-jaas") and it works fine when i configure Form-Based authentication to work with it in tomcat7.
With Servlet 3.0, there is a login method in HttpServletRequest (https://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html#login(java.lang.String,%20java.lang.String)) so you can login like
public void doPost(HttpServletRequest req,HttpServletResponse resp)
throws ServletException,IOException{
String username=req.getParameter("username");
String password=req.getParameter("password");
try{
req.login(username, password);
PrintWriter out= req.getWriter();
out.println("<h2>Welcome</h2>");
} catch(ServletException e ){
PrintWriter out= req.getWriter();
out.println(e.getMessage());
}
}

Same session in different browser tabs in jsp-servlet [duplicate]

I've a filter used for the login. It performs a textual checking, on fields "Username" and "Password". If and only if the textual checking is correctly done the request goes to the Servlet. This latter performs the control that has to interact with the Database. Is this chain correct?
Preface: I gather you're using homegrown login instead of container managed login. For all ways, see How to handle authentication/authorization with users in a database?
The filter (the interceptor) shouldn't check the validity of the username/password combo. That's the responsibility of the servlet (the controller).
The filter should merely check if the user is logged-in or not (usually by just checking the presence of a session attribute) and then continue the request or block it by redirecting back to the login page.
#WebFilter("/*")
public class LoginFilter implements Filter {
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
HttpSession session = request.getSession(false);
String loginURI = request.getContextPath() + "/login";
boolean loggedIn = session != null && session.getAttribute("user") != null;
boolean loginRequest = request.getRequestURI().equals(loginURI);
if (loggedIn || loginRequest) {
chain.doFilter(request, response);
} else {
response.sendRedirect(loginURI);
}
}
// ...
}
The servlet should collect the submitted data, find the associated User in database and if found then store it as a session attribute and then redirect to the home page, else redisplay the form with validation errors.
#WebServlet("/login")
public class LoginServlet extends HttpServlet {
#EJB
private UserService userService;
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
}
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
Map<String, String> messages = new HashMap<String, String>();
if (username == null || username.isEmpty()) {
messages.put("username", "Please enter username");
}
if (password == null || password.isEmpty()) {
messages.put("password", "Please enter password");
}
if (messages.isEmpty()) {
User user = userService.find(username, password);
if (user != null) {
request.getSession().setAttribute("user", user);
response.sendRedirect(request.getContextPath() + "/home");
return;
} else {
messages.put("login", "Unknown login, please try again");
}
}
request.setAttribute("messages", messages);
request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
}
}
See also:
Our servlet-filters wiki page
Our servlets wiki page

Can a session expire while being processed during doPost / doGet, if so what action can be taken

Currently I use the following filter to redirect user to index page after session is expired.
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest)request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
HttpSession httpSession = httpRequest.getSession(false);
if (httpSession != null && !httpSession.isNew()) {
chain.doFilter(request, response);
} else {
httpResponse.sendRedirect(request.getServletContext().getContextPath() + PathManager.getPagePath("index"));
}
}
But can the session be expired when executing code in doPost/doGet methods? So on entering the filter the session is ok, but the session expires inside the servlet's doPost/doGet method.
If such a scenario can happen, what is the solution to redirect the user to the login page?
You can throw an exception/message to the client when session has expired and then have the client redirect the user to the login Page.
To detect if session has been expired you will need to get the session from the ServletRequest and if it is null then it is expired.
//false parameter is used to return the existing session. if expired then null is returned.
final HttpSession session = request.getSession(false);

Session attributes getting lost

I am having a problem with a relativly easy thing. I am trying to do a simple program, where you can log in and log out using the session.
The session is created, but I am always getting forwarded to panel servlet and then to NoCorrectSession page. As if on login page the server saw isActive attribute, and then on panel page had not.
//class Login extends HttpServlet
private RequestDispatcher pageLogin, pagePanel, pageError; //defined in init()
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession();
String name = request.getParameter("name");
String isBeingRequested = request.getParameter("isBeingRequested");
if (session.getAttribute("isActive") != null) {
//user has been logged in before, redirect him
pagePanel.forward(request, response);
} else if (isBeingRequested != null) {
//user has entered data into the login page and submitted it
if (name.length() == 0) {
//user has not stated his name
pageError.forward(request, response);
} else {
//otherwise access is granted and account created
session.setAttribute("isActive", "yes"); //setting session to active
pagePanel.forward(request, response);
}
} else {
//neither of these? user just entered the login screen
pageLogin.forward(request, response);
}
}
//class Panel extends HttpServlet {
private RequestDispatcher pageNoCorrectSession;
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession();
//session has expired or never was started
if (session.getAttribute("isActive") == null) {
pageNoCorrectSession.forward(request, response);
//session valid
} else {
//logged in - do stuff
}
After digging in the project it turned out I've not made a mistake in these servlets, but in HTML code causing submitting a form directly to the panel servlet (and not creating the account object in the process). I know it is silly, but it was a great lesson. Expect the unexpected :P

JSP login page session timeout

I have created a login page for mock of hotel administrator. Now I want to add session time function to it. In other words, let's say the user leaves the computer (he is still logged into the admin webpage) for like 10 minutes or so. Then when he come back, I want to end the current session and then redirect to login page (this is more secured and his personal info would never be lost!).
How do I make that happen?
public class LoginServlet extends SpringInjectedServlet {
#Autowired
private LoginService loginService;
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String id = req.getParameter("id");
String password = req.getParameter("password");
String error = null;
//code for checking correct input
}
// mock
private boolean check(String id, String password) {
return loginService.authenticate(id, password);
}
#Override
public void init() throws ServletException {
System.out.println("LoginServlet");
}
}
Use Authentication Filters to check for Session in every request like
HttpSession session = request.getSession();
if (session == null || session.getAttribute("username") == null) {
// Forward the control to login.jsp if authentication fails or session expires
request.getRequestDispatcher("/login.jsp").forward(request,
response);
}
This will check for login username from session for every request if its null or the session expired ,it will redirect to login page.
Add this in web.xml
<session-config>
<session-timeout>5</session-timeout>
</session-config>
Check it here.
After you've verified the credentials, set a session variable for the userid, and to set the session expiration:
session.setMaxInactiveInterval(600); //600 secs = 10 mins
session.setAttribute("userid", userid);
Then at the top of all your JSPs and in all your servlets you do something like:
String userid = (String)session.getAttribute("userid");
if(userid==null)
{
response.sendRedirect("login.jsp");
return; //the return is important; forces redirect to go now
}
After the 10 minutes have elapsed, this will only redirect the user to the login page if they click a link, refresh, or somehow go to another page. If they just leave the page sitting there open, it will still display. To change that you would have to involve Javascript somehow.

Categories