Python requests module login using session - python-requests

I have a intranet application which i'm able to login using username/password.
Im trying to access the same application using python requests passing my username/password but that does not work. Its a difficult task to get a application support.
Meanwhile, I want to see if I can login using the session the web application created which is in my other browser.
How can I just pass the session using the requests module.

You may need to send data among username and password (usually this data is generated randomly by the server and are inside <input type="hidden"> form elements) which we prevent the CSRF (cross-site request forgery) attack. You may also need to send cookies the Web server send to you.
So, to solve your problem you need to:
Create a requests session to handle cookies;
Request the login page (where the form is) and extract CSRF data;
Post CSRF data among your credentials to the form action URL.
The code will be like this:
import requests
LOGIN_URL = '...' # put URL here
# replace 'user' and 'pass' with form field names for credentials
CREDENTIALS = {'user': '...', 'pass': '...'}
session = requests.session()
# get cookies and CSRF data
response = session.get(LOGIN_URL)
csrf_data = ... # extract data from response.text in a dict
# post data
csrf_data.update(CREDENTIALS)
# you may change LOGIN_URL below with form's 'action' URL if they differ
response = session.post(LOGIN_URL, data=csrf_data)
# now check response.text to see if you're logged in
There are many ways to extract CSRF data, such as: simple string manipulation, regular expressions or more specialized libraries such as lxml and BeautifulSoup (it depends on your input HTML and familiarity with the methods).

Related

HTTP Connector in Microsoft Power Automate - Login against Azure AD app registration on behalf of user not working

I hope you are doing fine :)
I have the following problem/problems.
I have created a dummy (robot) user. In Azure AD there is an App Registration with some Power BI delegated permission services.
I want to automate the deletion of a push dataset via a HTTP request.
For this, I need to authenticate against that App Registration from Azure AD. With postman, everything worked perfectly, I got the token as a response.
Then, I tried to make the same request using the HTTP connector in PowerAutomate.
I get the following error
{"error":"invalid_request","error_description":"AADSTS900144: The request body must contain the following parameter: 'grant_type'.\r\nTrace ID: e6d68953-ce1c-4217-856c-ae3aada82e00\r\nCorrelation ID: f50db4d9-d5bb-4396-af11-214717721f43\r\nTimestamp: 2022-10-26 19:12:48Z","error_codes":[900144],"timestamp":"2022-10-26 19:12:48Z","trace_id":"e6d68953-ce1c-4217-856c-ae3aada82e00","correlation_id":"f50db4d9-d5bb-4396-af11-214717721f43","error_uri":"https://login.microsoftonline.com/error?code=900144"}
The connector looks like this->
I have tried other ways as well.
The following error ->
{"error":"invalid_grant","error_description":"AADSTS50126: Error validating credentials due to invalid username or password.\r\nTrace ID: fec65949-0701-4727-af3b-2c2b8eb73a00\r\nCorrelation ID: 42c6c04b-98be-477d-8d36-52a01a473a40\r\nTimestamp: 2022-10-26 19:23:50Z","error_codes":[50126],"timestamp":"2022-10-26 19:23:50Z","trace_id":"fec65949-0701-4727-af3b-2c2b8eb73a00","correlation_id":"42c6c04b-98be-477d-8d36-52a01a473a40","error_uri":"https://login.microsoftonline.com/error?code=50126"}
I get from the the next HTTP connector inputs. I tried creating a query out of the previous json. It says the username or password are invalid but I logged in successfully for a number of times with those exact credentials. That I am sure of.
The dummy inputs in the picture are used to avoid the real ids, username and password.
This worked for me ...
Add a header setting Content-Type to application/x-www-form-urlencoded and add the URL form encoded content string like thus ...
client_id=<CLIENT_ID>c&grant_type=password&username=<USERNAME>&password=<PASSWORD>&scope=User.read
If you're using the password grant type approach, you shouldn't need a client secret, just the client ID.

Odoo Rest-API Failing to authenticate

I created a rest-api module in odoo12 and am using postman to check the end points but i get the error below on attempting to authenticate user
No CSRF validation token provided for path '/web/session/authenticate/'
Odoo URLs are CSRF-protected by default (when accessed with unsafe
HTTP methods). See
https://www.odoo.com/documentation/12.0/reference/http.html#csrf for
more details.
if this endpoint is accessed through Odoo via py-QWeb form, embed a CSRF
token in the form, Tokens are available via request.csrf_token()
can be provided through a hidden input and must be POST-ed named
csrf_token e.g. in your form add:
if the form is generated or posted in javascript, the token value is
available as csrf_token on web.core and as the csrf_token
List item
value in the default js-qweb execution context
if the form is accessed by an external third party (e.g. REST API
endpoint, payment gateway callback) you will need to disable CSRF
protection (and implement your own protection if necessary) by
passing the csrf=False parameter to the route decorator.
A quick but not recommended fix could be adding csrf=false in authenticating method route as they said in 3rd point not sure why not recommended but may make the route from web less secure but for API it's all good
from odoo.addons.web.controllers.main import Home
class HomeExt(Home):
#http.route(csrf=false)
def authenticate(self, db, login, password, base_location=None):
request.session.authenticate(db, login, password)
return request.env['ir.http'].session_info()

webdriver not returning all cookies

I am trying to test a scenario where an http request is ran to login to a site using username and password and on success it redirects to google.com.It also creates session cookies of its own which I am able to view in the Firefox browser manually.
However when I am trying to retrieve all cookies using Selenium Webdriver, it is just returning the cookies that belong to the present domain.
I am using the following code:
Set <Cookie> allCookies=driver.manage().getCookies();
Iterator <Cookie> itr=allCookies.iterator();
APPLICATION_LOGS.info("Cookie Size--->"+driver.manage().getCookies().size());
while(itr.hasNext())
{
Cookie c=itr.next();
APPLICATION_LOGS.info("Cookie Domain--->"+c.getDomain()+"Cookie Name---"+c.getName()+"Cookie Value---"+c.getValue());
}
Please let me know if there is any other way to retrieve all the cookies.

Issue with Response.Redirect to another site

I'm creating a gateway app which will control access to various other apps (tools).
On visiting the site the user is identified and a list of tools they have access to is displayed. Clicking the link takes the user to the tool. The URL is affixed with a token as a querystring. The token is encrypted.
On arriving at the tool site the system checks to see if there is a querystring with a token. It checks to see if the token is valid (the date is part of the encryption). If OK then the token is also saved as cookie which is valid for 8h and access is granted.
If the user hits the Tool site directly from a bookmark the system once again checks to see if there is a token and that it is valid. If no token is passed as a querystring then the system will see if it still has a valid cookie. If there is no valid token or cookie the site invokes a response.redirect to the gateway together with two querystrings t and r. t is the tool's numeric ID and r is the Tools URL.
What should happen is that the user will be redirected to the Gateway which will check to see if the user has access to tool id t and if the have redirect back to r with a fresh token appended as a querystring.
My code has the following....
Private GatewayURL As String = "http://GatewayURL/default.aspx?t=2&r="
Private ToolURL As String = "http://ToolURL/default.aspx"
In my page load I have….
…
If AuthenticationPass = False Then
'We are not authenticated...
Response.Redirect(GatewayURL & ToolURL, True)
End If
…
Unfortunately when this is triggered I get the following error...
Invalid path for child request 'http://GatewayURL/default.aspx'. A virtual path is expected.
I've run out of ideas on resolving this.... any help appreciated.
You should URL encode your query string parameters:
Response.Redirect(GatewayURL & HttpUtility.UrlEncode(ToolURL), True)
so that you redirect to:
http://GatewayURL/default.aspx?t=2&r=http%3A%2F%2FToolURL%2Fdefault.aspx
instead of:
http://GatewayURL/default.aspx?t=2&r=http://ToolURL/default.aspx
The second is a pretty broken url.

How to allow secure login across multiple domains

I have a web based application that allows a user to point their DNS at my IP and my app will serve up their content based on the domain name I see in the HTTP host header. I should point out this is done by the application, not by the actual HTTP server(apache), it is a rebranded app sort of thing. The problem I have is that I would like the users to be able to login through a form on the served page and somehow stay within the domain of the user. This is easy, unless you want security. I would have to have a SSL cert installed for every domain to pull this off. Right now I can do it by submitting the form to a domain with an SSL cert installed, but due to browser security I can't exactly set the required cookies on the original domain.
Does anyone know a way I can securely log in users through the app that does not involve installing a lot of ssl certs. I can think of some convoluted ways using redirects or other mechanisms, but it is not that clean. I don't mind a submit to the secure url and a redirect, it's just setting the cookie can't be done.
I've done this before using the following method...
Create auth key on server 1.
create_auth_key
expires = time + expire_time
data = username + '|' + password + expires
secret = 'my secret key'
hash = md5( data + secret )
key = base64( data ) + hash
On server two you pass the newly created authkey
valid_auth_key(key)
hash = key[-hash_size:]
b64data = key[:-hash_size]
data = base64decode( b64data )
data_hash = md5( data + secret )
if data_hash != hash:
return false # invalid hash
data_parts = data.split('|')
user = data_parts[0]
password = data_parts[1]
expires = data_parts[2]
if now > expires:
return false # url expired
return true
It's kind of quick and dirty but only relies on simple data passed via URL. The down side is that a specific url is all that's required to login and someone could share that url for a period of time. You also have to make sure your expiration time is not greater than the time difference between servers.
A common trick is to pass data in the URL. Facebook Connect does this. You can redirect from one domain to the other with a session token in the URL and then verify the token (perhaps convert to a cookie) when the request comes in on the other domain. Edit: the MSDN article that Facebook links to has much more detail.

Resources