Allow each user to have a single session - java

The webapp I'm working on is running JSP and JAVA in the backed on Tomcat server.
How would it be possible to only allow each user to have only one session at a time, meaning not allowing any user to sign in more than one from same or other machine/browser.
The JSP client side:
<input type="text" name="uname" placeholder="Username"> <br>
<input type="password" name="pwd" placeholder="Password"> <br>
<input type="submit" value="Login">
<% String fail = request.getParameter("loginFailed");
if(fail != null && fail.equals("yes"))
{
out.println("<br><font color=\"red\"> Login failed</font>");
}
else if(request.getParameter("loggedOut") != null)
{
out.println("<br><font color=\"red\">You have been logged out.</font>");
}
%>
JAVA Part:
public class login extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* #see HttpServlet#HttpServlet()
*/
public login() {
super();
// TODO Auto-generated constructor stub
}
/**
* #see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
String[] uname = request.getParameterValues("uname");
String[] pass = request.getParameterValues("pwd");
if( uname.length == 0 || pass.length == 0)
{
response.sendRedirect("/MASC/index.jsp?loginFailed=yes");
return;
}
UsersDB authdb = new UsersDB();
User authUser = null;
try {
authUser = authdb.auth(uname[0], pass[0]);
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(authUser == null)
{
response.getWriter().append("not authenitacted");
Cookie authCookie = new Cookie("auth", "no");
response.addCookie(authCookie);
response.sendRedirect("/MASC/index.jsp?loginFailed=yes");
}
else
{
System.out.println("auth session " + authUser);
HttpSession session = request.getSession();
session.setAttribute("uid", authUser.getUid());
session.setAttribute("level", authUser.getLevel());
session.setAttribute("aeid", authUser.getAeid());
session.setMaxInactiveInterval(15*60);
response.sendRedirect("/MASC/welcome.jsp");
}
}
/**
* #see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
Is there a way to store the logged in users, or create a new column in the database "Loggedin" and check for that column before allowing user to sign in? Or is there any more efficient way to implement that ?

First, you'd need to define what should happen when user logs in using a different session. Remember, if the user closed the browser, your server is not notified, so a new session can even be from a restart of the same browser.
Given that, I think the only way it makes sense, is to invalidate the existing session of the user, when the user logs in again.
To do that, you should create an application-scoped attribute (on ServletContext) with a map of user to active session. When logging in, you replace the current entry, if any. For every other access, if current session is not the active session, redirect to login page.

Create a map with userid as key and session object as value. Whenever a login request is received first check in this map the value corresponding to user id. If the value is not null, it means a session already exist for this user. So either invalidate the existing session and create a new one or use the previous one and display a message to user that user is already logged in. Point to note is that whenever a user log off, its entry in the map must be removed. You can use sessioncontextlistener for this.

Related

Losing Session on POST

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.

How to fetch data from servlet using ajax?

First of all, this might seem like a duplicate but I assure you I have tried many questions and still hasn't got a proper answer. So I'm asking this here.
I have an HTML form from which I would like to submit a query to a servlet and show the results in a different division.
My HTML code essentially consists of the following:
<form>
<input name="query" id="query" placeholder="Query">
<button id="searchDoc">Search</button>
</form>
<div id="search-results"></div>
I have the following jQuery in order to handle the ajax call.
$('#searchDoc').click(function() {
var q = $('#query').val();
$.ajax({
url: "QueryServlet",
data: {query:q},
success: function(data) {
alert("data: " + data);
$('#search-results').html(data);
}
});
});
My QueryServlet is:
#WebServlet("/QueryServlet")
public class QueryServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* #see HttpServlet#HttpServlet()
*/
public QueryServlet() {
super();
}
/**
* #see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
String query = request.getParameter("query");
QueryUtil qu = new QueryUtil();
String mySqlQuery = qu.buildMySQLSearchQuery(query);
System.out.println(mySqlQuery);
Connection con = null;
Statement st = null;
ResultSet rs = null;
try {
con = new DbConnection().getConnection();
st = con.createStatement();
rs = st.executeQuery(mySqlQuery);
if(rs != null) {
response.setStatus(HttpServletResponse.SC_OK);
while(rs.next()) {
out.println("" + rs.getString("fileName") + "");
}
} else {
// TODO add keywords to database
}
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* #see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
Even when I submit a valid query, the div does not get loaded up with the data from the servlet. The data reaches the servlet and gets displayed in the console, but I am unable to retrieve that data from the script.
The <button> tag is equivalent to an <input type="submit"/>. If you in your form tag don't declare any action attribute, the standard action causes that the page is reloaded. This causes that, although the returned data are inserted in #search-results div, you'll never be able to see them, because the page is immediately reloaded.
You should deactivate the default "Submit" button this way:
$('#searchDoc').click(function(e) {
e.preventDefault();
[....]
});
This should fix your problem!
the issue seems related to context path, your path should look like this if servlet is not in context root :-
<host> / <context path>/ <servlet>
Thanks :)

Declare a session variable golbaly to access from DoGet and DoPost in a sevlet

I have a servlet where I need to declare a session which can be acceptable form doGet and doPost both how I should do this?
I have done
#WebServlet(name = "LoginLogout", urlPatterns = {"/LoginLogout.do"})public class LoginLogout extends HttpServlet {//For Session
HttpSession session = request.getSession(true);
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
}
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String status = request.getParameter("status");
System.out.println(status);
}
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
String loginId = request.getParameter("login_id");
String password = request.getParameter("password");
System.out.println(loginId);
//Inserting value to the Pogo named "newLoginPogo"
loginData newLoginPogo = new loginData();
newLoginPogo.setLoginId(loginId);
newLoginPogo.setPassword(password);
//Creating a obj of ModelLogin to send the loginId and Password via a method which is in ModelLogin class
ModelLogin loginBis = new ModelLogin();
loginData userData = loginBis.checkUser(newLoginPogo);
String userExist = userData.getUserExist();
System.out.println(userExist);
if ("yes".equals(userExist)) {
System.out.println("In while loop of Servlet");
String firstName = userData.getFirstName();
String userId = userData.getUserId();
boolean IsSu = userData.getIsSu();
//conveting boolean to string
String superuser = new Boolean(IsSu).toString();
//Creating a session
session.setAttribute("firstName", firstName);
session.setAttribute(userId, "userId");
session.setAttribute(superuser, "IsSu");
//==============================================================================================================
//If user does exist show the Success Message and forward Dashboard
//==============================================================================================================
//Session for success message
String succmsg = "Login Successful";
session.setAttribute("succmsg", succmsg);
getServletConfig().getServletContext().getRequestDispatcher("/WEB-INF/ViewPages/dashboard/dashboard.jsp").forward(request, response);
} //==============================================================================================================
//If user does not exist show the Error Message
//==============================================================================================================
else if ("no".equals(userExist)) {
//Session for success message
System.out.println("inside NO");
String emsg = "Login Error";
session.setAttribute("errmsg", emsg);
getServletConfig().getServletContext().getRequestDispatcher("/index.jsp").forward(request, response);
} else {
}
/*
//===============================================================================================================
//code for Logout
//===============================================================================================================
String status = request.getParameter("status");
if ("logout".equals(status)) {
//clearing the session
session.invalidate();
//forwarding to index page
getServletConfig().getServletContext().getRequestDispatcher("/index.jsp").forward(request, response);
}
*/
} finally {
}
}}
But it says
Can Not find Symbol
in this line HttpSession session = request.getSession(true);
You don't need to have session variable in servlet as field. In general - this is kind of common mistake. There will be only one onstance of servlet serving lots of requests, and unless you declare it as single-threaded - the requests would be handled concurrently.
HttpSession will be pre-exist for you in doGet and doPost via request object. Servlet container will guarantee this. So simply obtain reference to the session in doGet/doPost and do whatever you want.
What you desire is one of the roles of HTTP session.
You can look at it as a conversation between the client and the server.
As long as the "conversation" (HTTP session) is open and alive, you can set variables on the HTTP session, and access them from different requests that will sent on the same session.
Look at this as some sort of "shared memory" that exists during the "conversation time".
You can find many examples on how to do that over the internet.
Here is an example for session tracking.

What extra do I need to do while using HttpSession with GAE?

I read , to set a session attribute I need to put :
<sessions-enabled>true</sessions-enabled>
inside appengine-web.xml and also implement java.io.Serializable. (though I don't understand the reason for this !)
Following is one of the servlet that uses HttpSession :
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String userName = request.getParameter("username");
String password = request.getParameter("password");
ArrayList list = new ArrayList();
if(userName.compareTo("user") != 0 ) {
list.add("Wrong Username");
} else if(password.compareTo("password") != 0) {
list.add("Wrong Password");
}
if(list.isEmpty()) {
HttpSession session = request.getSession();
if(session.isNew()) {
session.setAttribute("UserRole", "PW :Admin");
session.setMaxInactiveInterval(900);
RequestDispatcher rd = request.getRequestDispatcher("abc/cpanel/PcPanel.jsp");
request.setAttribute("SessionStatus", "JC"); // Just Created
rd.forward(request, response);
}
} else {
response.sendRedirect("abc/cpanel/PcPanel_Login.jsp");
}
}
After validating the username and password and entering the if block,request should be forwarded to PcPanel Login.jsp but it doesn't happen.Intead a blank page appears with the address of this servlet. But if I remove/comment all the session junk,it works fine. Why does it happen ? Am I missing something or I making a mistake somewhere ?
Don't use isNew(). isNew() is only true when session is first established = when user first lands on any of your pages.
See the answer to this question: Session is NOT working - GAE/J

Reloading JSP page

I have an authorization frame displayed on every page and I want to keep that page displaying even if the user will choose to log in (using jstl tags i will simply put instead of this frame user info and link to shopping cart). How can i achieve that ? I have some ideas, but they all breaking out my controller design.
public class FrontController extends HttpServlet {
private ActionContainer actionContainer = ActionContainer.getInstance();
public FrontController() {
super();
}
/**
* Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
* #param request servlet request
* #param response servlet response
* #throws ServletException if a servlet-specific error occurs
* #throws IOException if an I/O error occurs
*/
#SuppressWarnings("unchecked")
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String page = null;
try {
Action action = actionContainer.getAction(request);
page = action.execute(request, response);
RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(page);
dispatcher.forward(request, response);
} catch (ActionNotFoundException e) {
RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(PageNames.ERR_PAGE);
request.setAttribute(AttributeNames.ERR_MESSAGE_ATTRIBUTE, "Unknown Action command: " + e.getMessage());
dispatcher.forward(request, response);
} catch (Exception e) {
RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(PageNames.ERR_PAGE);
request.setAttribute(AttributeNames.ERR_MESSAGE_ATTRIBUTE, "Exception:\n" + e.getMessage());
dispatcher.forward(request, response);
}
}
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
/**
* Returns a short description of the servlet.
* #return a String containing servlet description
*/
#Override
public String getServletInfo() {
return "Front Controller";
}
#Override
public void init() throws ServletException {
super.init();
Locale.setDefault(new Locale("ru","RU"));
}
}
I was thinking about of redirecting to especially written for this case page, which will redirect to the original page, or to check page string for null and reloading from controller the original page, but i cannot clearly understand how to do this.
Your question isn't clear enough. But I think you're asking how you can replace a certain component on a page (Login button) with an other (username, welcome message and shopping cart details) after the user logs in.
If I understand your requirements, then what I would do after the user logs in is set a cookie (or a value in localStorage). The cookie is added to the Set-Cookie response header by means of the addCookie method of HttpServletResponse. Here's an example:
Cookie userCookie = new Cookie("user", "uid1234");
response.addCookie(userCookie);
Then in your controller simply check if the "user" value is set or not and take the appropriate action. A tutorial on servlets with cookies.
If you need to handle the front-end component, and change values on the form without reloading the page, I would recommend using javascript to do this, you can find and remove the old DOM elements with new ones (User's name, Welcome message, shopping cart, whatever).
If your iFrame is doing the login, then on successful login, have it call a function in your top window that does the update after reading the updated values from the cookie.
If you want to handle this completely at the front-end, i.e. Javascript, then I would skip using cookies and use localStorage instead. There is plenty of help on Stackover and on the internet about what localStorage is, but I will suggest the YUI Storage Lite library which makes storing and loading data from localStorage very simple.
Regards,
Include the current URL as a hidden field of your authentication form. In the action handling the authentication, once the user is authenticated, redirect to this URL.
In the JSPs, test if the user is authenticated and include the authentication form or the shopping cart. This test can be done by just putting a boolean value in the HTTP session once the user is authenticated.

Categories