How to connect to and keep the session alive using python requests - http

I am trying to login to a site, and then view user details.
The API documentation from the site is:
LogOn : All Calls with JSON and return JSON type
post - https://www.bit2c.co.il/Account/LogOn {UserName:'',Password:'',SecondFactor:[optional]}
return true if OK , error list of strings if not
Balance - GET https://www.bit2c.co.il/Account/Balance
return UserBalance as JSON
I've tried connecting to the site using
import requests
session=requests.session()
session.auth = ("username", "pass")
session.post("https//www.bit2c.co.il/Account/Balance")
but i am getting response 200 and the response content is "you must login".
What am I doing wrong ?

What kind of session? What is on server-side? Can you post the raw request/response pair(s)?
If PHP or ASP runs on server-side, you must capture the Set-Cookie header of the response to the login request, find the session cookie and in consequent requests you must set the Cookie header with the session cookie name and value captured previously.

Related

jmeter -not adding authorization header to all http requests

i have a fairly simple testplan with following steps recorded
Thread Group
Recording Controller
HTTP Authorization manager
GET https://xxxx/user/login
GET https://xxxx/accounts/list
GET https://xxxx/user/settings
GET https://xxxx/partners/list
GET https://xxxx/user/logout
When i run this, i see jmeter adding the authorization header in the first user/login request and server responds with 200 OK. This is OK
i extract the session token from the login response and put it as a variable into the subsequent http requests.
jmeter is not adding the authorization header in the subsequent accounts/list request - this is OK
but then jmeter is adding the authorization header into the subsequent user/settings request - this is not needed as it defeats the purpose of sending the session token.
Again jmeter is not sending the auth token in partners/list but is sending it again in user/logout request.
So question is how jmeter determines when to add the auth header and when not?
The desired behaviour i want is for jmeter to send the auth header in the first user/login request but not in any of the subsequent http requests.
Any pointers appreciated.
thanks
HTTP Authorization Manager will add Authorization header to all the HTTP Request samplers it its scope, if you place it at the same level with the HTTP Request samplers - it will add the header to all of them.
If you need to apply the HTTP Authorization Manager to 1st sampler only - move it to be the child of the first sampler.
More information: JMeter Scoping Rules - The Ultimate Guide
Recording any scenario adds up the Header Manager in all the Http requests.
You are doing it in correct way, however still you have to make few changes in your scripts to run seamlessly.
Delete all the subsequent Header Manager under the accounts/list,user/settings,partners/list & logout.
Post the Login Request > extract the session > Add a Header Manager after Login request and pass the session there.
All the further request should be in the same thread so that the session get passed to each request.
Also while recording there are multiple requests that gets captured and for each scenario Jmeter maintains the session under Header Manager, hence this should never be the case that one request is getting the session while others not.
Thanks for the answer that helps.
What i did and worked well in the mean time is add an explicit authorization header to the user/login request with a beanshell preprocessor to base64 encode the username / password.
thanks anyways

Request and Response in asp.net

As per my understnding the difference between Response and Request is below
Request is - We request to server for like .aspx page
Response is - We get the .aspx page from server
So, I think, request is toward Server and response is what we got.
We have following terms
Request.QueryString
Request.RawUrl
Request.MapPath()
All these seems to go to server first and brings back the associated data. But the following term is contrary ?
Request.Cookies
Because the cookies creates at client side and value part is also fetched at client side using Response.Cookies
Your comments?
Query - 2 - Why it is useful to create/Access cookie using Request/Response.cookies? Because it can be created/fetched at client end in JavaScript.
Query 3 - Cookie resides at client end. Why do we send request to server ?
Query - 4 - Why do we write Response.Cookies? to go to server? Why? it creates at client end and accessed from client end. right? Why do we write Request.Cookies? Means fetching cookie information from server? Cookie is at client end. right?
"When a browser makes a request to the server, it sends the cookies for that server along with the request. In your ASP.NET applications, you can read the cookies using the HttpRequest object, which is available as the Request property of your Page class. The structure of the HttpRequest object is essentially the same as that of the HttpResponse object, so you can read cookies out of the HttpRequest object much the same way you wrote cookies into the HttpResponse object."
ASP.NET Cookies Overview
"Cookies are sent to the browser via the HttpResponse object that exposes a collection called Cookies. You can access the HttpResponse object as the Response property of your Page class"
Beginner's Guide to ASP.NET Cookies
Every time you send a Request to server, the cookies for that server are also sent.
Also, when the server sends you a Response it can include cookies for the next Request you send it to.
So Request.Cookies and Response.Cookies make perfect sense.
Both objects Request and Response "live" in the server. So Request holds the data sent by the User Agent (the Browser, like Chrome, IE, etc.). Examples of this data are, the POST and GET Variables, the User Agent, the language, IP Adress, and many more.
Response is the object that lets you send data to the User Agent (the browser), i.e. a Web Page, a stream of bytes (like a downloadable file), etc.
The cookies live in the client side, that's right, but is the browser that send this information, so this data comes in the Request object.
You receive the cookies via Request.Cookies, but you receive the cookies in the Server. If you are coding in C#, the code is in the Server point of view, so receive means, the server receives. If you want to access the cookies in the Client Side, you must use some client programming language like JavaScript.
I hope this helps.

RESTful Login Failure: Return 401 or Custom Response

This is a conceptual question.
I have a client (mobile) application which needs to support a login action against a RESTful web service. Because the web service is RESTful, this amounts to the client accepting a username/password from the user, verifying that username/password with the service, and then just remembering to send that username/password with all subsequent requests.
All other responses in this web service are provided in a JSON format.
The question is, when I query the web service simply to find out whether a given username/password are valid, should the web service always respond with JSON data telling me its successful or unsuccessful, or should it return HTTP 200 on good credentials and HTTP 401 on bad credentials.
The reason I ask is that some other RESTful services use 401 for bad credentials even when you're just asking if the credentials are valid. However, my understanding of 401 responses are that they represent a resource that you are not supposed to have access to without valid credentials. But the login resource SHOULD be accessible to anyone because the entire purpose of the login resource is to tell you if your credentials are valid.
Put another way, it seems to me that a request like:
myservice.com/this/is/a/user/action
should return 401 if bad credentials are provided. But a request like:
myservice.com/are/these/credentials/valid
should never return 401 because that particular URL (request) is authorized with or without valid credentials.
I'd like to hear some justified opinions one way or the other on this. What is the standard way of handling this, and is the standard way of handling this logically appropriate?
First off. 401 is the proper response code to send when a failed login has happened.
401 Unauthorized
Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet been provided. The response must include a WWW-Authenticate header field containing a challenge applicable to the requested resource.
Your confusion about, myservice.com/are/these/credentials/valid sending back 401 when you just do a check, I think is based on the fact that doing boolean requests in REST often is wrong by the RESTful constraints. Every request should return a resource. Doing boolean questions in a RESTful service is a slippery sloop down to RPC.
Now I don't know how the services that you looked on are behaving. But a good way of solving this is to have something like an Account object, that you try to GET. If your credentials are correct, you will get the Account object, if you don't want to waste bandwidth just to do a "check" you can do a HEAD on the same resource.
An Account Object is also a nice place to store all those pesky boolean values that otherwise would be tricky to create individual resources for.
401 should be sent only when the request needs authorization header field and authorization fails. Since the Login API doesn't require authorization, hence 401 is the wrong error code in my opinion
As per the standard here https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
*10.4.2 401 Unauthorized
The request requires user authentication. The response MUST include a WWW-Authenticate header field (section 14.47) containing a challenge applicable to the requested resource. The client MAY repeat the request with a suitable Authorization header field (section 14.8). If the request already included Authorization credentials, then the 401 response indicates that authorization has been refused for those credentials. If the 401 response contains the same challenge as the prior response, and the user agent has already attempted authentication at least once, then the user SHOULD be presented the entity that was given in the response, since that entity might include relevant diagnostic information. HTTP access authentication is explained in "HTTP Authentication: Basic and Digest Access Authentication" [43].*
If the 401 response code is misleading for user authentication, the API can send HTTP status code 200 OK for both successful and failed authentication, but set a custom header on the authentication successful response and omit that header on failed logins.
The client can check if the header exists or not and decide the action.
Example: SpringBoot API Response
The call to OK when login is successful sets the header "gotyouin" with a value (anything). Call to failed does not add the header and client can treat this as a failed login attempt.
public class LoginResponseEntityHelper {
public static ResponseEntity<?> ok(String token) {
return ResponseEntity.status(HttpStatus.OK).header("gotyouin", token).body(null);
}
public static ResponseEntity<?> failed() {
return ResponseEntity.status(HttpStatus.OK).body(null);
}}
It is logical to use 401 http status code when access to a resource is denied because the request lacks or has incorrect credentials. And when correct credentials are provided, the request should complete successfully granting access to the protected resource.
Applicable for your case: myservice.com/this/is/a/user/action.
Maybe we should be clear about this credentials
In most secure applications, credentials are needed to access protected resource(s). These credentials can be sent along every request via HTTP header. Specifically the Authorization Header.
Therefore the Authorization header contains credentials to allow a user to access protected resource(s).
Remember that a user who was verified successfully as an authorized user(successful login), is the one given this priviledged credentials to allow for access on protected resources on the server.
From the server point of view, a HTTP request targeting a protected resource yet it is lacking credentials or containing invalid credentials may cause to validly send back 401 response code.
Therefore the Login API should not send a 401 response code because of a failed login attempt. It is misleading. Reasoning out that you are requesting to the server application via the Login API to grant you with credentials required to access resources that are protected. By itself, the Login API is not a protected resource.
So what is the correct response status?
Well I will opine towards sending back a 400 response code because a failed login attempt is a client error who is at fault for not providing the correct username or password.
According to RFC standards about 400 code:
The 400 (Bad Request) status code indicates that the server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing)
Again I will reiterate that failed login is a client error due to providing details that are incorrect. Sending back a 400 doesn't have to mean that the request syntax is malformed. But a malformed syntax is one of the reasons.
Sending a 401 would really be misleading as the user doesn't need to provide authentication information to access the login API.

Cookie handling in Google Apps Script - How to send cookies in header?

I'm trying to write a simple script that fetches text from a webpage and processes that string. But, that website requires me to be logged in. I was successful in logging in to that website. This is how I logged in:
var payload = {"name1":"val1","name2":val2"};
var opt ={"payload":payload,"method":"post"};
var respose = UrlFetchApp.fetch("http://website.com/login",opt);
After logging in, the website places me in http://website.com/home. I checked response.getContentText() and I can confirm that I have been logged in successfully as it contains the text from http://website.com/home.
Now I need to get the contents of http://website.com/page and process it.
I first assumed the script can handle cookies by itself and proceeded with
var pagedata = UrlFetchApp.fetch("http://website.com/page);//Did not work
That obviously didnt work and pagedata.getContentText() says me to login first, which indicates cookies were not successfully passed..
I then tried to extract cookies which the server responded during login and to send it along with this request.
var cookie = response.getAllHeaders()['Set-Cookie'];
// variable cookie now contains a legitimate cookie.
// It contains 'JSESSIONID=blabla;Path=/' and
// it is the ONLY cookie that server responds.
I tried to send that cookie in my page request.
var header = {'Cookie':cookie};
var opt2 = {"header":header};
var pagedata = UrlFetchApp.fetch("http://website.com/page",opt2);
I think even now cookies were not properly sent, as the content again says me to login.
Am I passing cookies correctly? I need help regarding the correct method of sending cookies in a request.
Here you can find cookies specification:
http://www.w3.org/Protocols/rfc2109/rfc2109
You have a potential issue in your code:
response.getAllHeaders()['Set-Cookie'] can return either a string or a table of string if multiple 'set-cookie' attributes are sent back from the server.
Eric is right, you cannot return the cookie without digesting it.
Second error in your code:
var opt2 = {"header":header};
should be
var opt2 = {"headers":header};
Be aware also that GAS uses Google IPs. It can happen that two consecutive fetch use different IPs.
The server your are connecting to may be session-IP dependant.
Are you sure the server only send you back one cookie after an authentification ?
It looks like you are setting the headers correctly in UrlFetchApp.fetch().
I believe that the data in the Set-Cookie header is in a different format than the data that is expected in Cookie header. For example, Set-Cookie contains information about expiration, etc.

ASP.NET form losing POST values in a proxy environment

I have an ASP.NET form (a login page), when I POST the values to the server, the request passes through a proxy and the POST pareameters end up getting lost and ultimately the page just refreshes as there are no POST parameters.
The thing is that this is not a constant issue as sometimes you can log in fine and generally if you clear your browser temp files it then works ok.
I ran Fiddler to check what's going on and basically I'm getting:
A regular POST request containing session id, POST data etc. The response (HTTP 407) contains a Proxy-Authenticate: Negotiate and Proxy-Support: Session-Based-Authentication header
The next request to the server contains a Proxy-Authorization: Negotiate header containing a long string (base64 i think). This request does NOT contain the POST values. The response is another 407 and actually now that i look at it Fiddler displays 'HTTP/1.1 407 Proxy Authentication Required ( Access is denied. )' as the header.
Then there's a third request that contains the Proxy-Authorization header and returns 200 OK, but of course the POST values weren't sent
Subsequent requests result in a HTTP/1.1 407 Proxy Authentication Required ( The ISA Server requires authorization to fulfill the request. Access to the Web Proxy filter is denied. ) response followed by a second successful but empty request.
The client wont let me bypass the proxy as it's intermittent and all other pages in the application (that include plenty of web forms) work fine.
Any ideas on what I can try?

Resources