Use SSO in python - python

I am new to the SSO world, so perhaps I miss already answered question.
I run an app in python3 and I need to make some API calls.
To do so, I need to be identified using my corporate SSO.
I know the SSO is stored as a cookie but I do not know how to:
Open a browser
Connect
Close the browser
Get the cookie
Do stuff
If possible without external library.
Also, I can ask my user to define its credentials as variable if it eases the process.
Thank you for any help

Related

Python requests, Kerberos and NTLM

I've been recently working on a project in which I need to access a asp.net web API in order to get some data. The way I've been gaining access to this API so far is by manually setting the cookies manually within the code and then using requests to get the information that I need. My task now is to automate this process. I get the cookies by using the Chrome developer tools, in the network tab. Now obviously the cookies change every once in a while so I've been trying to make something that will automatically change the cookies inside.
I should mention that the network at which this is being done is air-gaped and getting python libraries inside is kind of tedious, so I am trying to avoid that. It is also the reason why getting code examples here is very complicated.
The way the log-in process works in this web app is as follows (data from chrome dev tools):
Upon entering the URL there are a bunch of redirects which seem to do nothing.
A request is made to /login.aspx which returns a "set-cookie: 'sessionId=xyz'" header and redirects to /LandingPage.aspx
A request is made to /LandingPage.aspx with said cookie which returns a "set-cookie" header with a bunch of cookies (ASP.NET etc'). These are the cookies that I need in order to make the python script access the API.
What's written above is the browser way of doing things, when I try to imitate this in python requests, I get the first cookie from /login.aspx but when it redirects to /LandingPage.aspx, I get a 401 Unauthorized with the following headers:
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
After having done some reading I understood that these response headers are related to NTLM and Kerberos protocols (side question: if it responds with both headers does it mean that I need to provide both authentications or that either one will suffice?).
Quick google search yielded that after these mentioned responses should follow a request with the Kerberos/NTLM token (which I have no idea how to acquire) in order to get a 200 response. I find this pretty weird considering the browser doesn't make any of these requests and the web app just gives it the cookies without it seemingly transferring any NTLM or Kerberos data.
I've thought of a few ways to overcome this and hopefully you could help me figure out whether this would work.
Trying to get the requests-kerberos or requests-ntlm libraries for python and using those to overcome this problem. I would like your opinion to whether this would work. I am reluctant to use this method though, because of what was mentioned above.
Somehow using PowerShell to get these tokens and then somehow using these tokens in python requests without the above mentioned libraries. But I have no idea if this would work either.
I would very much appreciate anyone who could maybe further explain the process that's happening here in general, and of course would greatly appreciate any help with solving this.
Thank you very much!
Trying to get the requests-kerberos or requests-ntlm libraries for python and using those to overcome this problem. I would like your opinion to whether this would work. I am reluctant to use this method though, because of what was mentioned above.
Yes, requests-kerberos would work. HTTP Negotiate means Kerberos almost 100% of the time.
For Linux I'd slightly prefer requests-gssapi, which is based on a more maintained 'gssapi' backend, but at the moment it's limited to Unix-ish systems only – while requests-kerberos has the advantage of supporting Windows through the 'winkerberos' backend. But it doesn't really matter; both will do the job fine.
Don't use NTLM if you can avoid it. Your domain admins will appreciate being able to turn off NTLM domain-wide as soon as they can.
Somehow using PowerShell to get these tokens and then somehow using these tokens in python requests without the above mentioned libraries. But I have no idea if this would work either.
Technically it's possible, but doing this via PowerShell (or .NET in general) is going the long way around. You can achieve exactly the same thing using Python's sspi module, which talks directly to the actual Windows SSPI interface that handles Kerberos ticket acquisition (and NTLM, for that matter).
(The gssapi module is the Linux equivalent, and the spnego module is a cross-platform wrapper around both.)
You can see a few examples here – OP has a .NET example, the answer has Python.
But keep in mind that Kerberos tokens contain not only the service ticket but also a one time use authenticator (to prevent replay attacks), so you need to get a fresh token for every HTTP request.
So don't reinvent the wheel and just use requests-kerberos, which will automatically call SSPI to get a token whenever needed.
it says that in order for requests-kerberos to work there has to be a TGT cached already on the PC. This program is supposed to run for weeks without being interfered with and to my understanding these tickets expire after about 10 hours.
That's typical for all Kerberos use, not just requests-kerberos specifically.
If you run the app on Windows, from an interactive session, then Windows will automatically renew Kerberos tickets as needed (it keeps your password cached in LSA memory for that purpose). However, don't run long-term tasks in interactive sessions...
If you run the app on Windows, as a service, then it will use the "machine credentials" aka "computer account" (see details), and again LSA will keep the tickets up-to-date.
If you run the app on Linux, then you can create a keytab that stores the client credentials for the application. (This doesn't need domain admin rights, you only need to know the app account's password.)
On Linux there are at least 4 different ways to use a keytab for long-term jobs: k5start (third-party, but common); KRB5_CLIENT_KTNAME (built-in to MIT Kerberos, but only in recent versions); gss-proxy (from RedHat, might already be part of the OS); or a basic cronjob that just re-runs kinit to acquire new tickets every 4-6 hours.
I find this pretty weird considering the browser doesn't make any of these requests and the web app just gives it the cookies without it seemingly transferring any NTLM or Kerberos data.
It likely does, you might be overlooking it.
Note that some SSO systems use JavaScript to dynamically probe for whether the browser has Kerberos authentication properly set up – if the main page really doesn't send a token, then it might be an iframe or an AJAX/XHR request that does.

Where does Flask store the sessions?

I have recently started learning Python. I am currently trying to build a simple Web Application that requires a login to access some paths.
I understand that this can be achieved by using something like session['user']=user_id in Flask.
Can somebody help me with how exactly this works? Like where does Flask store the sessions if not in the database table?
It stores it in a cookie on the client side. From the official documentation:
This is implemented on top of cookies for you and signs the cookies cryptographically. What this means is that the user could look at the contents of your cookie but not modify it, unless they know the secret key used for signing.
If you need server-side session store, there is an extension called Flask-Sessionstore that lets you choose the method of storage, including server-side DBs.

What does it mean to use an API key in server-side auth flow?

New to programming, using Python 3.
I work in sales and want to make a program using the Podio API which is going to take information about potential clients from an excel sheet and use it to create subpages in Podio with their information. To get an API-key, Podio wants a redirect-URL for the purposes described here and here, a whole bunch of text I don't really understand. Does it mean I have to authenticate myself in my program (using my Podio login info?), which sends me to Podio (where I log in to Podio manually, using the same login info?), which sends me to the redirect URL, which sends me back to Podio? I can't really make sense of this.
I googled and found some similar questions but none of the answers explained exactly what the actual functions of these authentication flows are. When do I need them? Do I need them if I'm just going to be using this program myself? Do I always need them to gain access to my Podio account through my program?
Thanks in advance.
If you are only going to use your program yourself, then username/password flow is what you need. It is simplest to understand and use flow of authenticating with Podio API. Here are all needed details for it: https://developers.podio.com/authentication/username_password
To be short: yes, you can enter localhost as full domain (without protocol) of your return URL

Where to store web authentication session in PySide?

I'm building a little application in Python. I use PySide for the GUI and Django to read data from my web application.
Everything works well, but I have a login access, like dropbox application.
I want to store this informations on the current machine (like a session, I don't want to login every time I open the application).
Now my question is, what is the safest way to do this? Environment variables?
Usually when you have an API that you're exposing in your app to the outer world (even your own desktop/mobile app), you'll design this API to be stateless, as part of the REST architecture. So your app should always include an HTTP header or any other method of carrying an authentication token that will let your API identify the user.
You only log in once, and when the log-in procedure is successful you should get an authentication token from your API, and then you will store this token somewhere safe.
You can also look into implementing OAuth2 for the authentication.

How can I call an endpoint in my appengine instance without doing oAuth? (Mirror API)

I am trying to create some Glassware with the Mirror API. I am new to using AppEngine and Jinja2. I have python experience but never with a web framework before. So basically I am very new at this.
I have modified the Python quickstart for the mirror API to include many of my endpoints and designs. Basically I want to be able to be able to POST data from a constrained device to Glass. I have an endpoint all setup which works to accept and parse out the data and send the timeline item.
My problem is that the device itself is acting all on it's own and cannot provide input, therefore when I call my app from it e.g. https://foo.appspot.com?operation=deviceData the app presents the auth page and then nothing happens. I can see in the logs that the auth page is being sent, but the device has no idea what to do with this.
Basically, I need a way where I can hardcode credentials and get around having to do oauth everytime. What is the recommended way to do this? Another app which doesn't require auth which passes the data along? This would be fine as I only need to set this up with one user right now, it is for an internal demo only.
Is it possible to set my credentials in a header and auth automatically without handling any return, more like how basic auth works?
There are also the "Simple API access" keys. Would these work in this situation, I tried creating browser and server keys and tried them on the device and in the browser by doinghttps://foo.appspot.com?operation=deviceData&key=KEY_HERE but in both cases I was still prompted to login. Is this what simple access keys are for? Do they not work with the mirror API?
Basically my question is, what's the easiest way to allow access to my apps endpoints without having to oAuth or having a hard coded user which auto-auths?
Here is the project that I started with: https://github.com/googleglass/mirror-quickstart-python

Categories