/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: [email protected]
> For additional commands, e-mail: [email protected]
>