How should I implement an Auth handler that takes effect on response? - python-requests

I wish to implement an Auth handler for requests that handles authentication with an OAuth Authorization server to allow the following:
import requests
requests.get(url, auth=KeycloakAuth())
What I've done so far is to apply a response hook when KeycloakAuth is called, so that when the client redirects the caller to Keycloak, the hook will see the Keycloak login page, post the credentials to Keycloak and get redirected back to the client.
However, this does not work for a POST, as requests makes a POST to Keycloak's login page instead of a GET due to the redirect. Keycloak doesn't return the login form in response to a POST and this fails.
I considered checking for the redirect in the response hook so that I can modify the redirect to do a GET to Keycloak instead, but it seems like requests' implementation of redirects bypasses all the hooks.

After poking into this a bit more, I believe this may be the wrong question to ask.
I was seeking a solution where, regardless of the original HTTP method used on the client (GET, POST, HEAD, etc), the library would automatically login to Keycloak, and then "replay" the original request to the client and make it effectively transparent to the user of the library.
However, this can't possibly work with OAuth 2.0 without further state management on either the part of the library or the client, due to the redirecting.
Suppose the original request was a POST, with some data. After finding that the user is not logged in, the User-Agent will be redirected to the Authorization Server for authentication.
This means that the original request's POST data will be lost, removing the opportunity for any replay, upon the User-Agent being redirected back to the client after authentication.
With some state management, the POST data could be stored for replay - it doesn't make sense to store the data on the server side since the data could be arbitrarily large, which leaves us with the user of the library to do the state management.
However, that amount of state management should probably not belong in a library, since the library will have to handle lots of cases to guarantee only-once delivery of the request, for example, which would be expected by the user of the requests library.
As such, this Auth handler is probably not something we can implement in a library.

Related

How to attach Authorization header when redirecting POST request?

We have a third party service that implemented single-sign-on on some route to it’s web-app.
In order to use this single-sign-on, we provided with a POST API, and we need to pass on that route some credentials- including an organization secret that we got from him (yes, we need to pass it in query params), and the user’s email address.
In order to not to expose credentials over the browser, we tried to mimic that request by creating our own backend endpoint, and return the same result as their enpoint (kind of a proxy) with redirection (status 307 with Location header) cause there API returns plain HTML.
It seems like when client send a post request with redirection he can’t add the authorization header (JWT) required by our backend to operate (backend return Authorization required). the request is been done to our server and the result is redirection to another server.
How can we bypass it? Or maybe we can secure it with different approach?
I know that the header is usually been removed for a good reason, who knows where I can be redirected to?
but can't I tell him somehow that I trust the redirection?
We tried to use phantom-form only to use from submit post. We tried to make our endpoint to be GET and making the redirection other way (react-router) but I think that natively js does not allow to attach Authorization header.
I thought it would be a common pattern, but I didn't find someone that talks about it exactly, since we are trying to query our backend and not some external redirection API.

Should I use post requests over get requests?

So basically I am working on an API that has authenticated routes and in order to access the route, you must pass a token and a userId. The way I currently have this implemented is the token in an Authorization header and the userId in the req body.
However, I find myself sending post requests for methods that are really meant for get requests such as fetching a user's search history but since the route is protected, I need to send the token and userId which forces me to use a post request instead.
This has made it so that all of the typical get requests are post requests. I read that post requests are slower than get requests but since the request body is so small, I don't think performance is really an issue.
But still I just want to make sure: Is it appropriate/acceptable to use post requests instead of get requests?
I know that it obviously works, but is it proper API "architecture"?
Thank you!

Postback for Passwords in Cleartext?

I've just started working on an aspx web from login page for AspNet.Identity.
I have my fields, username and password (textmode="Password") and a submit button (asp:button) as usual with my code behind to do login, etc.
My question is, when my user clicks submit, how is the password sent to the server? Do I need to be on SSL to ensure that the password isn't sent in cleartext?
Edit
StackOverflow's login page isn't over HTTPS - how do they (and other sites that don't use HTTPS) manage password transmission?
One can say that all data submitted from the browser is sent in cleartext (that is, neither browser itself encrypt it, nor when data arrives to your server-side script it requires decryption). All the encryption (if any) is performed at the protocol level.
Plain HTTP doesn't encrypt any information sent over it, which allows for simple inspection (man-in-the-middle attack, eavesdropping). On the other hand, HTTPS creates a secure channel over an otherwise insecure network and protects from said attacks reasonably well.
One caveat to that is using GET to send data to the server. This information can easily end up in server logs.
Depending on the form method GET or POST values are sent to the server.
By default in asp.net the form method is POST so it is send in the body of the request.
If the form method is GET then it sent in the url.
Edit 1
When you use HTTPS the channel is secured. But some time it can be slower than HTTP because HTTPS requires an initial handshake which can be very slow.
Some useful links
Difference between http and https
HTTP vs HTTPS performance
Main problem is that if anyone is able to listen to the traffic from your client to your server, then they will also be able to manipulate what your server sends to client. This issue invalidates all attempts to do some javascript magic to hide it out will be lost effort.
In other words, there is for the time being only SSL to help you out.

How can webservers detect replayed login attempts?

I found a strange thing when i'm coding a net-spider to a specific website.
I used fiddler and chrome(as well as other web-browsers) to log-in a website(HTTP, not https) and get all package(as well as the cookie) that sent and received:(
first package 'Get' to request the log-in page and the cookie, then use the cookie received to request verification code and some other pics. and then send login request with userid, password and verification code to server and server response with correct info)
Then I log-out and Clear all Cache and Cookie and use Fiddler to Relay(Simulate) the whole process (Since I know all packages' format that i should send): request the log-in page to get cookie, use the cookie to request all pics( auth code image included), and then use the cookie and auth code to request login(userid and password are correct)...but failed.
I'm sure the failure is not caused by invalid userid or password or auth code, and i believe there is nothing special on the front-end(html,script are checked), but it puzzled me a lot how can the server tell i used browser or not in back-end..
I'm not request anybody to solve the specific problem. i'm just wanna know DOES ANYONE HAS HAD SIMILAR PROBLEM i described?
the specific website is not important and i must say the whole practice is completely harmless! i'm not doing any hacking stuff, on the contrary it will help some people.
======================================================
I've finally figured out the reason: the log-in page has a hidden input() and i carelessly overlooked that since its value looks almost the same every time. Web server can not detect replayed log-in attempts if we simulated all necessary HTTP request packages.
Thank you guys~
Servers cannot magically tell whether they're talking to Fiddler or not.
If Fiddler and your client are sending the exact same requests, that means that the server in question is using a "one time token" (sometimes called a nonce) in its login form. If the server ever sees the same token again, it rejects the logon. Sometimes the nonce isn't sent directly, and is instead used in the computation of a "challenge-response" as occurs in authentication protocols like NTLM. In other cases, the nonce is a CAPTCHA, which helps prevent you from using a bot to automatically log in to a site like this.
Unless you can share more details of the target site (or a SAZ file of the login process), it's unlikely that folks will be able to help you.

Pass value from one ASP.NET app to another via HTTP Header

We are implementing a single sign on mechanism in an enterprise environment, where the token is shared between applications using HTTP header. Now, in order to do the integration test, I need to write an application to simulate this.
Is there any way in ASP.NET where I can redirect to another web-page and pass a custom HTTP header in the process?
Thanks
You need to create a page on Site B that Site A redirects the user too that sets a cookie with the desired value.
for instance.
http://siteb.com/authenticate.aspx?authtoken=15128901428901428904jasklads&returnUrl=http://siteb.com/index.aspx
authenticate.aspx would set a cookie and then every request would receive authtoken.
The server could send the HTTP header to the client on a redirect, but the client would not send it back to the other remote server.
The ideal solution in this case would be to use a Cookie, or a QueryString variable. Cookies may suffer from cross-domain issues and become complicated if host names are different enough.
In any of these approaches, one must be careful not to create a security hole by trusting this information as it is user input coming back from the client (or some black hat).

Resources