/context1 is used just for directing users to the right application (or context). Session is really maintained by /context2. Users can login directly in /context2 or they can input username and password in /context1 and they will be forwarded to the right context on of which is /context2. So the login information could come to /context2/Login.action via a direct POST to this action or via a forwarded request from /context1.
The testing I have done is completely on /context2. Have some users login at /context2/Login.action while JMeter tries to access /context2/Login.action and another action /context2/PlanList.action (requests to any action other than Login.action will get forwarded to Login.action if the user is not yet logged in). So a direct request to /context/PlanList.action will end up at /context2/Login.action. I can't say that 2 percent of users were able to get in without username/password. As I have ran the JMeter tests a lot of times (each run with 100 users). Only during one of those runs of JMeter I had 2 requests get users home page when Login.action was requested (with out username/password). Below is the Login.action code. Removed the code that fetches the data for home page. Thanks, Prasanth public class LoginAction implements ServletRequestAware{ Logger log = Logger.getLogger(this.getClass()); private HttpServletRequest request; private String message = ""; private String username = ""; private String password = ""; private String action = ""; public String execute() throws Exception { String result = null; boolean displaySuccessPage = false; // SEE IF THE USER SESSION IS ALREADY THERE, IN WHICH CASE NO NEED TO DISPLAY LOGIN PAGE // MOVE TO SUCCESS PAGE Long censusID = null; HttpSession session = request.getSession(false); if(session != null) { if(session.getAttribute("username") != null && session.getAttribute("CensusID") != null) { // GET THE CENSUS ID AND DISPLAY SUCCESS PAGE censusID = (Long) session.getAttribute("CensusID"); if(censusID != null & censusID > 0) { // JUST MADE SURE THAT WE HAVE A VALID CENSUS ID displaySuccessPage = true; } } } // IF ACTION IS LOGOUT THEN LOGOUT THE USER // OR IF THE USER DECLINES DISCLAIMER if( ("Logout".equals(action) || "Decline".equals(action)) || (request.getParameter("Submit") != null && request.getParameter("Submit").trim().equals("Logout"))){ // INVALIDATE THE SESSION request.getSession().invalidate(); message = "You have been successfully logged out"; username = ""; password = ""; displaySuccessPage = false; result = "secure"; } // IF THE PARTICIPANT HAS ACCEPTED THE DISCLAIMER UPDATE THE DATABASE else if("Accept".equals(action)) { censusID = (Long) request.getSession().getAttribute("_CensusID"); if(censusID != null) { Utils.updateDisclaimerCode(censusID); // SET THE USERNAME & CENSUSID. REMOVE THE TEMPORARY VARIABLES request.getSession().setAttribute("username", request.getSession().getAttribute("_username")); request.getSession().setAttribute("CensusID", request.getSession().getAttribute("_CensusID")); request.getSession().removeAttribute("_username"); request.getSession().removeAttribute("_CensusID"); request.getSession().setAttribute("dispContactInfo", Plans.getDisplayContactInfoCode(censusID)); displaySuccessPage = true; } } // IF USER IS NOT ALREADY AUTHENTICATED else if(!displaySuccessPage){ // IF USERNAME IS NOT PROVIDED DISPLAY LOGIN PAGE if(username.equals("")){ request.getSession().setAttribute("maintenanceMessage", Utils.getMaintenanceMessage()[0]); request.getSession().setAttribute("suppressLogin", Boolean.parseBoolean(Utils.getMaintenanceMessage()[1])); result = "login"; } else{ // USER NAME SPECIFIED SO TRY TO AUTHENTICATE //GET THE IPADDRESS OF THE CLIENT String remoteHost = request.getHeader("X-FORWARDED-FOR"); if(remoteHost == null || "".equals(remoteHost.trim())) { remoteHost = request.getRemoteAddr(); } //AUTHENTICATE USER censusID = Utils.authenticate(username, password, remoteHost); if(censusID == -1) { message = "Invalid username/password specified"; result = "failed"; } else { new com.xxxxx.xxxxx.model.Logger().loggedIn(censusID, remoteHost); String[] maintenanceMessage = Utils.getMaintenanceMessage(); if(Boolean.parseBoolean(maintenanceMessage[1])) { // SITE UNDER MAINTENANCE request.getSession().setAttribute("maintenanceMessage", maintenanceMessage[0]); request.getSession().setAttribute("suppressLogin", Boolean.parseBoolean(maintenanceMessage[1])); message = "Website is under maintenance"; result = "failed"; } else { // USER HAS BEEN LOGGED IN SO CREATE A NEW SESSION session = request.getSession(); session.setAttribute("username", username); session.setAttribute("CensusID", new Long(censusID)); session.setAttribute("censusId", new Long(censusID)); session.setAttribute("dispContactInfo", Plans.getDisplayContactInfoCode(censusID)); synchronized (request.getSession().getServletContext()) { // INCREMENT THE USER COUNT int userCount = 0; if(request.getSession().getServletContext().getAttribute("userCount") != null) { userCount = (Integer) request.getSession().getServletContext().getAttribute("userCount"); } userCount++; log.info("User Count:" + userCount); request.getSession().getServletContext().setAttribute("userCount", userCount); } displaySuccessPage = true; } } } } if(displaySuccessPage) { // CODE TO DISPLAY HOME PAGE xxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxx } // GET SITE NEWS ITEMS Calendar cal = Calendar.getInstance(); LinkedHashMap<String, String> news = Plans.getNews(-1, new Date(cal.getTimeInMillis())); request.getSession().setAttribute("siteNews", news); return result; } /** * Sets the client id and client name in the session. * @param censusId * @param request * @throws SQLException */ private void setClientId(long censusId, HttpServletRequest request) throws SQLException { HashMap<Long,String> clientIdAndName = Utils.getClientIdAndName(censusId); if(clientIdAndName != null){ for(Long clientID: clientIdAndName.keySet()){ request.getSession().setAttribute("ClientID", clientID); request.getSession().setAttribute("ClientName",clientIdAndName.get(clientID)); } } } @Override public void setServletRequest(HttpServletRequest request) { this.request = request; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getAction() { return action; } public void setAction(String action) { this.action = action; } } On 03/07/2018 04:22 AM, Yasser Zamani wrote: > > On 3/5/2018 7:48 PM, Prasanth wrote: >> For replicating the issue I was directly accessing /context2/Login.action. >> So /context1 was not used in testing. > Please let me repeat what I understood; When some users are signed in > into /context1, you browses /context2/Login.action via JMeter empty > requests, but about 2 percent of them, successfully sign in into /context2! > > Did I understand the issue correctly? If so, it's very odd ... and I > like strange issues :) > > Does this issue also happen even when no one is signed in into > /context1? If so, does this issue also happen when /context1 is stopped > (i.e. /context2 never get any forwarded request from /context1 so far)? > I ask these to know if this issue is dependent to the app on /context1 > or not. > > I see you use Undertow web server and I reviewed it and saw it's highly > non-blocking async web server. Then ... please add a hidden field to > your login.jsp which it's value will be > request.getParameter("testIfStrutsReusesAction"). In JMeter add > testIfStrutsReusesAction=JMeter to your request parameters. Then re-run > JMeter and see if those two successful requests have a hidden field with > value "JMeter" in their response?? (also see that other requests must > have this hidden field elsewhere there is a problem in your impl of > these). I ask these to know if that successful response is really a > response for your JMeter request! > > If none of above were helpful, then could you please share > /context2/Login.action? I need to see how do you authenticate? Only via > request params? Or session or something else makes sense also? > > Regards. > > --------------------------------------------------------------------- > To unsubscribe, e-mail: user-unsubscr...@struts.apache.org > For additional commands, e-mail: user-h...@struts.apache.org >