Identifying cookies - asp.net

I have an ASP.NET Core web app with an API that requires users to be authenticated. About a month ago, I realized I could no longer use Postman API tool because even though I'm authenticated, my API calls would get a response as if I'm not authenticated.
When I look at available cookies under cookies tab, I see four of them. I recognize one of them but not the other 3.
The cookies I'm seeing in the "Cookies" tab in Postman while making API calls are:
ARRAffinity
.AspNetCore.my_cookie
_ga
_gid
All four cookies are showing my domain. The only difference I've noticed is that the second cookie show mydomain.com while others show .mydomain.com. I recognize the second one because I name my cookie i.e. my_cookie. That one is also the largest one which also makes sense because I store some information in the cookie. I assume, .AspNetCore prefix is added by my app because it's an ASP.NET Core web app with API.
What are the other three cookies? Do I need them?
The other important thing I've noticed is that when I use Fiddler to inspect my API call, under "Cookies" tab in Fiddler, I only see the tree cookies that I couldn't identify being sent with the API call. I do NOT see the one that I recognize which is issued by my site.
Looks like my issues with Postman have something to do with these three unidentified cookies being sent with the API call but not the one that I issue i.e. .AspNetCore.my_cookie is NOT being sent with my API call.

_ga and _gid are used to collect Google Analytics data.
Name - Expiration Time - Description
_gid - 24 hours - Used to distinguish users.
_gat - 1 minute - Used to throttle request rate.
if you want to know more about Google Analytics cookies, please read this
In the other hand, for ARRAffinity. Windows Azure Web Sites, by default, use an ARRAffinity cookie to insure subsequent requests from a user are routed back to the web site instance that the user initially connected to. In other words, Windows Azure Web Sites assumes your web site is not stateless. If you were to scale your web site deployment to multiple instances, the ARR Server processes this ARR Affinity cookie and sends you back to the instance that processed your initial request (the request that originated the cookie).
If you’re not already familiar with this, check out this blog for an in-depth discussion on ARR Affinity for Web Sites and how to disable ARR Affinity if your web site is stateless.

Related

How to load test login having Sitefinity - Azure AD B2C Authentication oauth2 with JMeter

There are multiple requests being passed in signing in of the application since its using Sitefinity - Azure AD B2C Authentication and there are some values being passed in each requests such as nonce, state properties, id token etc. The workflow is quite complicated when having a peek into the values/token being passed across the requests of login. Though I have created/tried with all the values that are getting as the response of previous requests, still the login is not happening. Also, I went through some documents of B2C authentication with Sitefinity and its architecture and I got to know that the token being generated by the Sitefinity is an internal process and the response of that token cannot be fetched from a previous response/ client side.
Workarounds that I did:
Integrated selenium into Jmeter and automated the login scenarios and stored the cookie generated. Then used these cookie and token in following internal requests- This approach worked fine.
Hardcoded a live cookie in Cookie Manager and send the internal requests - This also worked fine.
I am wondering if there is any other possibilities in logging in because the above two methods are not reliable in long run. Anyone have idea about generating the token id locally and pass that to JMeter. for example creating a .exe file which generates the Sitefinity token.With this we will be able to pass or execute the .exe file in OS Process Sampler in Jmeter and fetching the token from its response.
Or
Any other approach?
I assume you are using the OpenIdConnect authentication provider that is built into Sitefinity?
So, basically when a user clicks on the Login button, he is being redirected to:
/login/LoginExternalProvider/OpenIdConnect/
Here Sitefinity replies with a redirection to:
/Sitefinity/Authenticate/OpenID/connect/authorize?client_id=sitefinity&....
which in turn redirects to
/Sitefinity/Authenticate/OpenID/login?signin=....
and this finally redirects to the external authentication provider.
(yeah, it is a complex workflow).
So, if you try to load test only the first request (/login/LoginExternalProvider/OpenIdConnect/) - wouldn't it then follow the redirect responses automatically (sorry, not familiar with jmeter)?
Those responses contain the correct cookies that Sitefinity has created, etc.
As per Sitefinity documentation:
Sitefinity CMS uses claims authentication, implemented on top of IdentityServer3, certified by OpenID Foundation. It allows implementing single sign-on and access control for modern web applications and APIs. It uses OAuth2 and OpenID Connect protocols.
Standardized authentication, based on OpenID Connect with JWT, certified IdentityServer3.
Given you're capable of logging in using your browser - you can replicate the same requests using JMeter's HTTP Request samplers, it's just a matter of correlation - the process of extracting the dynamic data from the responses and using them in the next requests.
You can refer OpenID Connect - How to Load Test with JMeter article for example JMeter script implementation

Are all cookies passed in an HTTP request?

I am having trouble understanding how a session is restored via cookies. How do the client know which sessionID cookie to send to the server via the HTTP request the first time? Does the client send all cookies and the server accepts the one that it also knows?
For example, let's say there are websites A and B (both using PHP), and I logged into both websites and then closed my browser. Now I open the browser again and go to site A and see that I am kept logged in. In this scenario, when my browser sends the HTTP request, the cookie whose file name contains the session ID for site A must have been included in the header. However I have two sessionID cookies for both site A and B. As far as I understand, the host name is usually not stored in the cookie, at least in many PHP tutorials of the setcookie() function. How do my browser know which sessionID cookie is for site A? Does the browser just send all cookies to A and let A figure out which is the right one by comparing all the received session IDs with stored session IDs? This does not sound right to me.

Handle HTTP cookies to simulate browser like behaviour

There is a site which accepts logins from the same user until browser is restarted. I try to simulate this in JMeter with HTTP Cookie Manager. I defined cookies, use those in all the logins, but seemly it doesn't use those. After successful login site enables only the same user to login until browser is closed, but I can login with other users too in same JMeter test execution. I use standard Cookie Policy.
You don't need to define cookies manually, JMeter's cookie manager manages cookies automatically
As per the documentation:
The Cookie Manager element has two functions:
First, it stores and sends cookies just like a web browser. If you have an HTTP Request and the response contains a cookie, the Cookie Manager automatically stores that cookie and will use it for all future requests to that particular web site. Each JMeter thread has its own "cookie storage area". So, if you are testing a web site that uses a cookie for storing session information, each JMeter thread will have its own session. Note that such cookies do not appear on the Cookie Manager display, but they can be seen using the View Results Tree Listener.
If you need to mimic "Logout" you can tick Clear Cookies each Iteration box and each Thread Group loop (iteration) will simulate "clean" login.
See HTTP Cookie Manager Advanced Usage - A Guide for more information on HTTP Cookie Manager use and troubleshooting.
It is possible that the web site is not using cookies at all for the purpose of tracking logins, and instead uses "browser session storage". (See https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage) And it is possible that the cookies that you see are added by other parties / sources, for example google analytics etc.

How are user logins from a desktop application usually handled?

What is the common(best practice) way of allowing a user to sign in from a Windows desktop application. Some examples of what I mean are Dropbox or Google Picasa. You sign in with your credentials and then the software is permanently signed in.
I assume the communication takes place over HTTPS. Does the client store the credentials to be sent with requests or is there some sort of token generated? Can anyone point me to some resources on how this should be handled?
Logging into a website normally creates a session at the server. The server then has to identify subsequent requests by the session. Typically, there is one of the following two solutions applied:
Session cookie, storing a session identifier
URL rewriting, where the session identifier is appended to every link in the html source
Which approach is taken is site dependent, so if you are writing a general 'for all sites' client, you might have to implement both.
In the former case, your application will have to handle the session cookies, in the second case, your application has either nothing to do - if it caches the html response - or will have to emulate the url rewriting itself.
In both cases be aware that the session will expire at server side after a certain period without any activity, so you might be required to generate such.

add asp.net pages to an asp classic website

I have an asp classic web site and I want to add some new code. I would want to begin to code with .net. Is there an easy way of doing this.
I was thinking an iframe that call my .net pages, but how will I share my user that need to be logged in my asp classic web site.
If I would use an iframe, what would be the best technique to share my user. I was thinking of passing the crypted info in query: test.com?users=[mycrypteduser]. But how would I encrypt it?
I'm pretty sure you can mix aspx and asp files in a single web project. So, create web-proj, then drop your existing website files to it (from within VS). Then, slowly start to refactor your existing site to aspx, as you can, page by page, and create new pages as aspx, of course.
Using IFRAME over this approach will be a lot more work that one may anticipate. But, regardless, you're hitting the problem of 2 unrelated websites in the need to trust each other authenticated sessions - and, this is primarily solved by those websites communicating such information to each other in the background, without the direct involvement of the browser. You need to be able to change the code at both sites (so, you must own both sites). So, if you want to go that route, typically it'd be done this way:
User logs in to your asp site
Your ASP site calls a webservice at your ASP.NET site and informs it that the user will be coming with a particular one-time auth-token in query and that it should be trusted. The emphases here are: the webservice must be well protected by authentication mechanism (otherwise you're risking a huge security issue); the auth-token mentioned should expire after it's used once and only once (otherwise, you're opening your asp.net site for abuse). Typically, your ASP app would call a service at ASP.NET with a signature like this: string GetAuthToken(string username). ASP.NET app should store this info as a record in a database: username, some random and unique string value (e.g. guid), create time (with the precision of at least a second), and time used.
Your ASP app receives a one-time auth token from ASP.NET app.
Your ASP app would need to include this token into the URL used on the frame to a page at ASP.NET site.
Your ASP app would then serve the page with a frame to the browser.
The browser starts displaying the page, then it gets to displaying the frame to external asp.net page
The browser requests the asp.net url, which contains the auth-token
ASP.NET site receives the request and it assumes that the auth token is present and valid; otherwise, exception. Valid token is: never used (time-used in db mentioned in step 2), and valid (its existence in db). As the receiving page validates this token, it immediately checks it off as used. It's the best to put this logic as one atomic operation (e.g. a stored procedure, if you're using MS SQL Server). This way, you can execute both get-token and mark-token-used in a single step. This URL must be anonymous; you must have forms-auth on this site anyways, and this particular handler should be reachable by anon user. If you dislike making that exception, then maybe create an HttpModule, which would inspect every request, and act only on those that are anonymous and are containing the auth-token (by validating the token, and then, as appropriate, interrupting the request or letting it execute); this way, your framed page doesn't have to care about authentication, but it must be forms-auth protected also. I personally would do this that way (http module). Also, if you're sure that relatively short period of time will pass between step 1 and step 2 here (e.g. few seconds max), then do include token expiration in your token-validation logic (validation time must not be later than token-create-time + some number of seconds, e.g. 30) - just for extra security. Otherwise, if you don't implement expiration - imagine a user logging in today, which generates this never-expiring token, and a malicious user somehow getting a hold of the token string. Then, if the authenticated user never visited the page with the asp.net frame, then the token would be usable days, months, years from the moment it's issued, even after the real user closed their account. You don't want this risk. If the login page doesn't redirect to the page with the frame, then make the service call from that page instead (once per session). Ideally, the token should expire 30 seconds or so max after it's created.
If the token is valid, the part of your ASP.NET app that is validating the token would then be responsible for issuing forms-auth cookie. You'll find a ton of examples out there; keywords: FormsAuthentication, create cookie, authenticate user. Make sure that besides inserting the cookie into the response (which is done by default by FormsAuthentication module), you also set the identity of that current/particular request immediately, as until you do, your request is still considered anonymous. If you don't do that (and people do this, but I don't think it's necessary), you will have to redirect that request (which would force the browser to send up the auth-cookie that it just received in the 302 response).
Finally, your framed page receives an ok that the user checks out and that they may view the content that that page generates. Your page streams HTML down to the browser, and the browser shows that content in the frame.
Note that you will not be able to have any sort of client-side scripting (javascript) going on between the page and the frame (security reasons), and that would be another way why I'd rather mix asp with asp.net files (and slowly upgrading the asp part to asp.net), provided that makes sense in other business-related aspects.
Beware of shared-hosting issues related to outbound requests. Some hosts block all outbound traffic; so, if your asp app is in such environment, you won't be able to make that webservice call to asp.net. If you have the asp app making other/unrelated http calls across the internet (e.g. it talks to 3rd-party web services), you're good (it'll work); otherwise, do test this somehow, as you can never be sure. Also, even if your site runs in your own environment, companies often have outbound firewalls in place, so, you might have to request an exception for this.
Remember that the page-refresh will not be an issue, and you do not need to make the get-token call more then once per authenticated session. This is because the browser will, after the first frame load, have an auth-cookie from asp.net site, and the token (even if present in subsequent frame url), will not be validated (remember, the module validates token on anonymous session only; see step 8).
Do think about adjusting cookie expiration settings between the 2 sites. Imagine asp.net auth cookie expiring before the asp auth cookie expires: user reloads the page, and the iframe shows the login page on asp.net - ugly. So, your asp.net auth cookie should probably be set up to expire longer than asp auth cookie (however long you set it as, you won't fix the problem, as it's either wrong to set the cookie to not expire for extremely long time, e.g. 7 days, or it's theoretically possible that a user of your asp site will sit through all that time without touching the page with the frame after they saw it once, and your asp.net cookie will expire). So, do something like this maybe: set asp.net auth cookie to expire in 20/30 minutes (one of those is the default timeout value). Then, have asp app be aware of this timeout value. So, correction to my previous statement of one get-taken call per session. Instead, have the asp call the get-token service every time that you know the asp.net cookie already expired or might expiring soon. In other words, keep track of when you made the last get-token call for each user, and if 15 min (for example, where asp.net cookie expires in 20) has passed since last get-token call, make it again, change the frame url, and the frame will be authenticated once the existing asp.net cookie expires (which would be approx 5 min from that moment, in this example).
I keep coming back to edit this answer :) So, cookie expiration problem - assuming asp.net cookie expires in 20 min, and I told you to set the url on the frame every 15 min, while I also told you to make the token expire in 30 sec - so, those 2 things are conflicting. Hm, I wonder what's the best solution here... Maybe set the get-token to happen closer to asp.net cookie expiration (as in, e.g, at 18 min, but still less than 20), and set the token to be valid for, I don't know, 3 minutes). This would result in 18 + 3 = 21 to overlap the asp.net cookie expiration. All this because the user already has asp.net cookie. So, 18 min after that first cookie was issued, they visit the page with the frame, and the page decides to get another token. This starts token-ticker on asp.net site, and it sets the iframe url with new token. But, since existing asp.net cookie is still valid, the new token will not even be validated (remember the module only validating anon requests with token? Otherwise, you'll have too many db hits if you do it on every request), so the new token will not be used immediately. Eventually, asp.net cookie will expire (in 2 min), and the new token will be validated. If this is a problem (if I omitted some use case that essentially results in the login page displayed within the frame), then maybe you can implement some other mechanism to keep these cookies in place: maybe add code to the login page at asp.net to look for the token in ReturnUrl (decode, then load into NameValueCollection, then look for it as a normal querystring lookup), and maybe communicate back to the asp site something that would signal it to re-request the token when the frame comes back (and what I mean by this, redirect the framed login page, in this case only, back to a special asp script at asp site, which would re-request the token, and then redirect the frame back to asp.net with new token.
I told you it'd be a lot of work. Perhaps there is a standard that involves all this. Check out OAuth (http://oauth.net/) and OpenID (http://openid.net/); those methods are similar to what StackOverflow is offering as login alternate to SO accounts (Google, Yahoo, etc). However, that implies that you actually send the user to the asp.net site to login, then come back to the page that displays content from asp.net site. Perhaps you can combine this with the webservice call that I suggested (get-token ws, redirect top window with token in url to asp.net, asp.net will authenticate and redirect back, then page with frame will display). However, you still have the cookie expiration problem, as you need to constantly be able to get content from asp.net site (whereas, StackOverflow, for example, talks to Google on my behalf only once, during login, and never again during the session), but instead of that messy iframe redirect path that I send you, maybe you can simply repeat the login-to-asp.net-site routine every 15 min (get token, redirect there, validate token, redirect back). If you do this every 15 min at the whole asp site level, you should be fine - and, the user won't even notice this in most cases, as those redirects will be quick.
I'm sorry if this is a difficult read. I hope it helps, though. +1 if it does :)
You can create a new ASP.NET web application, and pull all of your classic ASP pages. Then when you deploy, the ASP.NET web application will overlay your classic ASP.
If you are using some sort of integrated authentication, both the ASP and ASP.NET pages will have access to the same identity. If you created your own authentication layer in the ASP application, you will need to recreate this in ASP.NET (for example, create classes that read/write the same authentication cookies that the ASP pages are using).
However, long term this will introduce some development friction switching between ASP and ASP.NET all the time, so I would really only suggest this approach if you are planning to incrementally convert your entire application from classic ASP to ASP.NET.
You can use NSession http://nsession.codeplex.com/ an open source project with objective to allow ASP Classic to access ASP.NET out-of-process session stores in the same way that ASP.NET accesses them, and thus share the session state with ASP.NET.
I have tried it out and it really works.
Happy Coding!!
When i face this issue, i have found the best solution is usually to use .NET as a web service, and use HTTPRequests in the ASP page to pull the data into your ASP page.
When sharing sessions with ASP and Classic ASP, the most common way is to NOT USE SESSIONS IN ASP, and Use Cookies, Database Cookies actually for the actual session verification, by GUID usually.

Resources