I have been working on performance testing for a while. I want to ask if there is any difference between running the test for 500 virtual users using the same username and password or should we be using different user for each virtual user.
If the test was executed with the same user, will the user data be cached on client or server sides and the results won't be accurate?
Thanks!
It is all about How realistic is your test scripts.If 500 virtual users login with different credentials of username and password, then it will mimic the real life scenario.Login with same credentials will not.
You should use "HTTP Cookie Manager" and "HTTP Cache Manager" in your Test Plan.Using "HTTP Cookie Manager" enabling "Clear cookie each iteration" and "HTTP Cache Manager" enabling "Clear cache each iteration" will at least bring some luck for 500 VUsers using same ID and Password. In this case, every user will be assigned with different session ID and the session cookie and cache will be cleared before next login using "Same Username & Password".So though ID and Password are the same but previous cookie and cache are cleared before new login. So the result will be more accurate and realistic.It basically depends on your test script design.
Though it is always appreciated and recommended to use different credentials despite using "HTTP Cookie Manager" and "HTTP Cache Manager" in your Test Plan.
IMHO, the load testing should simulate as closely as possible the real user behaviour, BUT the final answer is really dependent on your application, on the budget you have to do the test, and on the perception you have about how critical is scanning the user DB.
In one case, I had to create a number of user which was 10x the maximum number of virtual user I actually used in each test.
I think that simulating users connecting with the same account will most likely always hit the cache or the same components.
For example a cart on a web store: if you rely on the same user account, you will have concurrency issues when adding products to the cart. More information in this blog post: What makes a realistic load test?
Related
In implementation of Login, I want to make sure if a user is already logged in one tab of the browser and opens the same web site in another tab, he gets redirected to homepage rather than the log in page. It's an ideal scenario as it happens in all the web site. I am achieving the same by storing logged in unique user token in local storage. Is it the best way to achieve it? Kindly guide! is it safe? If not how to go about it?
Just consider everything on the client as tainted or possibly manipulated.
So basically you should always check on the server side if the client has a valid session and only then deliver the homepage to it.
I would use a cookie set by the server side - just a random id bound to the actual client session on the server.
So the client could mess with that, but would have a hard time to guess another (also random) session id.
The cookie should be cleared by the server if the user logs out.
Then I would check on every call if he has a valid session id and if not directly send him to the login page by a redirect. Additionally you could then send him from the login page to the homepage whenever he is already logged in.
Can login page (where we need to enter the credentials) be tested?
And URL of that website after login page can be tested without login?
JMeter is able to simulate login event and represent authenticated user. See i.e. ASP.NET Login Testing with JMeter guide for example configuration and associated correlations.
If you need to simulate N authenticated users and X unauthenticated ones you could use Throughput Controller for scenario distribution.
Answer is Yes and To a Large extent Yes.
Yes, Because it can be done for Web Page Logins and as Dmitiri said ASP.Net logins also.
Why i am Saying "to a Large Extent" is NTLM and Kerberos Authentication for Logins can be a bit troublesome. Where you need to be sure about the Domain names, the exact details.
Now, it depends where you are being asked for the User's Credentials . Normally for a Simple Web Page login - You Would get the URL from the address bar and you need to pass that.
For NTLM and Kerberos ones, you need to do some research so as to where you are getting authenticated and grab hold of that page.
We did for NTLM one and the login and authentication pages were different.
So, I have a web application that makes a lot of requests to the server for data. A project requirement is to have very fast server response times. The server is hosted on a cloud based platform.
The app uses sessions to keep track of user authentication once they've logged in. Since it's hosted on a cloud provider, I'm using a cache to back up session storage (in my case it's Auzre cache, but if you're unfamiliar with that think Redis)
The current flow is like this:
The user accesses a resource
Trying to get the session based on the session ID via the cache. This is a cache request.
User is authenticated via session state (if logged in).
Request for data is sent, usually via cache.
Data is returned to the user.
The problem with this approach is that it's hitting the cache twice. Removing the session altogether caused a significant speed improvement (about 50%).
I was considering hitting the cache once, asking for both the key I need for the user, and the SessionID to save the extra round trip. However, I've never seen this approach before, and it requires 'rolling my own session' as I'd have to generate the session IDs and such. I feel like there might be a simpler, easier way.
So, what would be the most efficient way to serve the user a resource and authenticate them?
Note: I'm using ASP.NET MVC/ WebAPI with C# but I don't find that very relevant to the question, so I left the language and platform out of the question because of it.
You would want to combine the authenticate and resource request steps into one single request. Not only is this faster, it is also safer than your implementation. Consider the following scenario:
User authenticate to the server. Result is success.
Authentication is changed. (e.g. user changes password, admin decides to lock the user account, etc.)
User makes a request using the sessionID in step 1.
To ensure that the user is not granted access to the resource, you'd want to authenticate the user precisely at step 3. But that doesn't make sense, you've already authenticated this user previously in step 1...
HTTP, in is core, is designed exactly to do this. There are various ways to pass authentication information along with the request, such as:
Write the authentication information in the content (stupid, but works)
Include authentication in the url, e.g. example.com/pic/123?sessionID=abc (better, but makes your url ugly and long)
Store session info in cookie (better, but what if the client does not support cookie? what about cookie expiration?)
Authenticate HTTP header (my best personal recommendation)
HTTP itself has an authenticate header meant to be compatible with "basic authentication" (it is well defined, look it up if you're interested). But you can implement your own custom header.
Any cache lookup is bound to be slow (compared to computation), so you should omit the cache for the authentication part all together. Your server should be stateless; i.e. do not keep track of login sessions. How do you know if the sessionID is valid? Put a timestamp on it. And to avoid others faking the sessionID, sign it as well.
So, your HTTP request would look something like this (pseudo code):
var request = new HttpRequest();
request.url = "example.com/pic/123";
request.Headers["CustomAuth"] = "id=abc&t=123456789&s=01de45890a";
Implement your own signing method, sort of like a hash function (you can use HMAC), and keep the key securely on the server. If the signature matches, you know you've signed this previously at the login, and it has to be from your server. A timestamp helps you detect session expiration and also protect against replay attacks.
Now in your server, do something like this:
public void Get(){
var authHeader = Request.Headers["CustomAuth"];
if(!validate(authHeader)){
Response.StatusCode = 404;
Response.End();
}else{
//something else
}
}
If you need to do login + session authenticate + resource request in one request, then there're simply just 2 ways for authentication. Users can either provide a username/password combination, or a session key. Think about this scenario, which comes from an API I worked on:
user register with username/password combo
server responds registration success / failure (e.g. username already taken)
if it was a success, user now logins with username/password combo
server returns a session token
Wouldn't it be simpler (and faster) if we do it this way:
user register with username/password combo
if it is success, respond "reg success" and "sessionToken=xxxxxx". if it is failure, respond "reg failure".
I hope this give you some idea.
Also, you can remove the authentication at the server end by modifying / restricting settings on the server to cater to requests coming only from the ip(s) where your web app is hosted. Your web application will let the request pass to server only if its authenticated and hence all the requests reaching the data server will be served automatically without checking for any authentication. In this case you will just need one cache hit to check if the user is authenticated and straight away hit the server.
I have this web app written in AngularJs that uses cookies to authenticate the requests in a REST API.
Once the user logs in, the cookie is received and saved in the browser and all subsequent requests send the cookie along to the server. There is a 'User' service/object that saves the isLoggedIn and username values (for UI display/flow). Now, if I refresh the 'index' page, the app restarts. This means that my 'User' object will be cleared. I can check the existence of the cookie and, if it exists, I can re-set the User.isLoggeIn as true and go from there, but I still need to get the username, id, etc. So, my question is: should I create some sort of 'ping' endpoint in the API to verify if a cookie is valid? And if so, the API would send me back the user id and username... OR should I persist the user data in LocalStorage (or some similar cross-browser thing) and just assume the user is logged if the cookie exists? Any other subsequent requests to pages that need authentication would be automatically verified. So, this question really only applies to the scenario where the user refreshes the index page - hence, restarting the web app. I want to know the user data because I want to show a 'user homepage' instead of the 'public homepage'.
What do you think?
You should depend on the server for this. Creating something like GetCurrentUser method on the server. If the user is logged on this returns all the properties of the user.
You should even use this server api to get the user data after authentication completes. So the authentication become two step process first the user is authenticated, on success another call is made to server to get current users details.
Using client side local storage for this would not be ideal because you need to do lot of book keeping, in terms of cleaning the logged in user on log out or session expiration.
Also cookies from server would have expiration times an all, and making decision just based on cookie existing on local storage may not be optimal approach.
I have a standard HTML login page, which I would much rather use than the standard HTTP authentication pop-up provided by browsers. Today, I am using session cookies to keep track of the session after logging in, but I'd like to be stateless and pass the HTTP authentication every time. The web services I am hitting already support this, so this is a browser-only issue.
Adding authentication credentials is trivial in jQuery, but I don't know how to keep them around. If you go from the login page (a jsp) to the Home page (another jsp) you clearly don't keep the username and password fields from the login page. I know some browsers will store your HTTP authentication credentials if you enter them from the pop-up, but I don't know if they get stored when using an XHRRequest. If they do, is there much consistency among browsers?
Also, the user needs to be able to "sign out" of the application, too. If the browser stores the authentication credentials, is there a way to clear them using JavaScript.
I feel like I can't be the first person to try to solve this. Is there some jQuery plugin or something that already handles this? Or is it simply not possible to do what I'm trying to do?
You have 2 options:
1) Client-side storage of credentials -- not a good idea. For obvious reasons you don't want to store the username/password on the client. If you had a hashed version of the password, it might not be so bad, but still not recommended. In any case, if you're going to store on the client side, you either have to use a cookie, or HTML5 local storage (which is not widely supported, yet)
2) Server-side storage of credentials -- typically done with sessions. Then the resultant Session ID can be passed back to the client and persisted in either a cookie or in the URL of each subsequent AJAX call (?SESSID=xyz for example)
The server-side approach would be the most secure, reliable, and easiest to implement
Okay, I'll take a stab at helping ...
Firstly, understand how HTTP authentication works. There are two versions - Basic and Digest. Basic transmits in plaintext, digest is encrypted. With these types of authentication, the username/password are passed in the HTTP header with every single request. The browser captures these at login and they are stored in an inaccessible browser session cookie which is deleted when the browser session is closed. So, in answer to one of your questions, you can't access these from javascript.
You could create your own session cookie variables for username and password. The jQuery functions for this are really simple. See jquery-cookie module as one example of how to set session cookies. These could be retrieved from the session cookie and sent with each ajax request and validated in the server. However, this is not a particulary good way to do authentication since sniffing the network will allow anybody to easily grab your auth details. But, it would work.
Using session cookie based authentication where the session ID is sent sent with each request is the best way to do this. At the server side, you need to have a function called for every HTTP request. This function should do the following:
check to see if the session has been authenticated
if no:
redirect to login screen
if yes:
do authorization and allow the user access to the page
Most web frameworks support session cookie authentication and the management of session ids at the server. This is definately the way to go.
This is interesting one.
Manage user sessions on server by use of cookies. Create a session when user first accesses the login page and pass the session id/key as value to one of the cookie via response. When the user is authenticated put user "key" info in cookie and "values" in application context at server. Once user is logged, any subsequent request will be authenticated based on session cookie value at server. Authorization will be done based on user "key" passed as cookie value.
On logout clear the session based cookies from server and refresh the site to default page.
Cookies are bizarre with different browsers - just a note ;)
Hope this helps.
Update
The answer below was posted in 2012 and the links are mostly dead. However, since then, a more elegant standards-based approach to the same solution appeared using JSON Web Tokens. Here is a good blog post explaining how to use them.
Most answers miss the point, which is to avoid having any server-side session. I don't want any application state in the server. I'll award the bounty to answer that came closest, but the real credit goes to the rest-discuss group and Jon Moore for the correct answer and to Mike Amundsen for helping me to actually understand it.
The best answer I've gotten is to use a cookie, but not the typical automatic session id cookie given to you by most application servers. The cookie (which will automatically be sent with each subsequent request) is a user identifier and time signed by the server. You can include an expiration time with the cookie so it simulates the typical 30 minute session on a server (which means you have to push it forward with subsequent requests) as well as keeps the same cookie from being valid forever.
The XHR/AJAX part is a red herring. This will work whether you are doing XHR requests or an old-fashioned page-by-page web application. The main points are:
The cookie is automatically sent on subsequent requests so there's no
special scripting required - it's just how browsers work already.
The server does not need to store any session for the user, so the user
can hit any server in a cluster and not have to re-authenticate.
Slightly interesting in that you consider pushing some of the authent to the client. If you want a conventional solution, KOGI's server-side suggestion is the way to go.
But you also seem to be asking questions about memory leaks involving your user supplied secrets. Good questions. But to take a general stab at answering that I'd say it would have to be browser specific. It's browser internals, javascript engine internals -dependent where a client side application (i.e., the browser, or js in the browser) is storing the values the user inputs.
Most likely those values are not replicated needlessly throughout memory, but there's no way to guarantee that. Apart from responsible javascript coding practices, there's nothing you can do to guarantee the limit of locations of user inputs.
Slight digression
The basic point is if you store it on the client it is not really secure -- unless, the serve stores encrypted information on the client with a key that only the server (or the user via their correct credentials), has. So you could conceivably code a JS application to do some authent on the client -- much the same as how bank card (used to?) do POS authent by checking the PIN to the PIN on the card, and not back at the DB. It's based on the (somewhat flimsy) assumption the user has no direct read/write access of the "dark area" cookie/local storage on client / mag strip on bank card. So I would only advise this as disqualifier for false authents and not as a sole qualifier for the credentials.
Main point
If you do want to be stateless, just store user credentials in localstorage, or as a cookie but encrypt them with a server key. When you need them send an XHR with the encrypted / use stored credentials to the server over HTTPS, let your server decrypt them and send them to the callback. Then pass those cleartext of HTTPS to do your authent.