struts-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Prasanth <dbad...@pangburngroup.com>
Subject Re: Struts2 login action class seems to be reused
Date Wed, 07 Mar 2018 16:04:01 GMT
/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-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
>


Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message