HTTP requests in python with basic authentication - python

I have a piece of code that includes several GET requests. I have a simple if statement to check the status code and provide auth if I receive a status code of 401. How do I avoid having a separate if statement for every single request line I have?
I'd like to be able to provide credentials only once if its protected instead of having to provide it with every single request.
EDIT - Added some code for reference
response = requests.get(self.uri + '/v2/apps')
if (response.status_code == 401):
print("It appears that your marathon instance is protected, please enter your username and password")
usr = input("Username: ")
pwd = getpass.getpass("Password: ")
response = requests.get(self.uri + '/v2/apps', auth=(usr,pwd)).json()

First, if you get a status code of 401, it means you're not authorized to use the resource.
Second, you have different options for authenticating the client once. Usually, I recommend looking into using HTTPS for transporting the data. You can use:
You can use a cookie with expiry
Using a token service in your web server
There multiple authentication standards (e.g. SAML, OAuth, OpenId, etc.) already existing, try not to reinvent the wheel.

Related

Python login to website requiring MFA token

I am attempting to create a login tool for my work which will log me in to various sites that log me out after 3 minutes of inactivity. I have gotten it to work on a number of sites, but none have required an MFA token. I currently use Google Authenticator but can also use an email, or a couple different options. How would I go about getting that code programmatically to make my login process much faster? I am using Selenium as I need to use the webpage after I log into it. Here is my code thus far:
def loginsys():
driver = webdriver.Chrome('C:/path/to/chromedriver.exe')
driver.get('https://www.specifiedurl.com/login')
username = driver.find_element_by_id('txtUsername')
password = driver.find_element_by_id('txtPassword')
username.send_keys("myusername")
password.send_keys("mypassword")
driver.find_element_by_name('btnLogin').click()
### This is where I need to do MFA as it will not pull the next page without it
driver.get('https://www.specifiedurl.com/page/after/login')
Thoughts? (Obviously, this is not the url, nor is that my actual username or password)
Check the pyotp library. You can get the MFA key associated with google authentication as shown below.
from pyotp import *
# get the token from google authentication
totp = TOTP("your 16 character security token goes here")
token = totp.now()
print (token)
# now you can use token in your script

Azure graph api returning different token each time a login attempt is made.?

I have a python api which accepts email and password from a login webpage. This email and password is used to login to azure ad and in response we get a access token which is valid for 1hr. Below is the sample python code:
context = adal.AuthenticationContext(config_data['AUTHORITY_HOST_URL'] + '/' + config_data['TENANT'], validate_authority="cceaddik-1q7c5-997ad-6453-sduf9347asit8" != 'adfs')
token = context.acquire_token_with_username_password(config_data['RESOURCE'], email, password, config_data['CLIENT_ID'])
print(token['accessToken'])
Normally this token generated for a user should be valid for 1hr and if same user is logging again within the same 1hr, it should get the same access token. But what I have noticed is that, each time we login, we are getting different access token. Why is this happening. Can anyone please throw some lights on it. Thanks.
You will always get a new token when you call Azure AD. It does not cache tokens there.
A token is valid for one hour from the time you requested the token.
As a side note, handling passwords is a bad idea in general.
It would be much better to use one of the interactive login flows like authorization code flow.
You cannot enable MFA for users for example, as the login would fail.

python3 upload files to ondrive or sharepoint?

Anyone know if this is possible?
I just want to automate dropping some documents into my onedrive for business account.
I tried
import onedrivesdk
from onedrivesdk.helpers import GetAuthCodeServer
from onedrivesdk.helpers.resource_discovery import ResourceDiscoveryRequest
redirect_uri = 'http://localhost:8080'
client_id = 'appid'
client_secret = 'mysecret'
discovery_uri = 'https://api.office.com/discovery/'
auth_server_url='https://login.live.com/oauth20_authorize.srf?scope=wl.skydrive_update'
#auth_server_url='https://login.microsoftonline.com/common/oauth2/authorize',
auth_token_url='https://login.microsoftonline.com/common/oauth2/token'
http = onedrivesdk.HttpProvider()
auth = onedrivesdk.AuthProvider(http,
client_id,
auth_server_url=auth_server_url,
auth_token_url=auth_token_url)
auth_url = auth.get_auth_url(redirect_uri)
code = GetAuthCodeServer.get_auth_code(auth_url, redirect_uri)
auth.authenticate(code, redirect_uri, client_secret, resource=resource)
# If you have access to more than one service, you'll need to decide
# which ServiceInfo to use instead of just using the first one, as below.
service_info = ResourceDiscoveryRequest().get_service_info(auth.access_token)[0]
auth.redeem_refresh_token(service_info.service_resource_id)
client = onedrivesdk.OneDriveClient(service_info.service_resource_id + '/_api/v2.0/', auth, http)
I registered an APP and got a secret and id. But when I ran this I got scope is invalid errors. Plus it tries to launch a webpage which isn't great for a command line kinda environment. I think this SDK might be outdated as well because originally this script had login.microsoftonline, but that wasn't reachable so I changed it to login.live.com.
I wrote this sample code you posted. You replaced the auth_server_URLwith the authentication URL for Microsoft Account authentication, which can only be used to access OneDrive (the consumer product). You need to continue using the login.microsoftonline.com URL to log into your OneDrive for Business account.
You are correct that this pops up a dialog. However, you can write a little supporting code so that only happens the first time you log into a particular app. Follow these steps (assuming you are using the default implementation of AuthProvider:
Use the sample code above up through the line auth.redeem_refresh_token()
The AuthProvider will now have a Session object, which caches the credentials of the current user and session. Use AuthProvider.save_session() to save the credentials for later.
Next time you start your app, use AuthProvider.load_session() and AuthProvider.refresh_token() to retrieve the previous session and refresh the auth token. This will all be headless.
Take note that the default implementation of SessionBase (found here) uses Pickle and is not safe for product use. Make sure to create a new implementation of Session if you intend to deploy this app to other users.
Onerive's website shows "Not Yet" on "OneDrive SDK for Python" to "OneDrive for Business"
https://dev.onedrive.com/SDKs.htm
The github sample codes did not work for me either, it tried to popup a window of authentication, but IE can not find the address:
http://('https//login.microsoftonline.com/common/oauth2/authorize',)?redirect_uri=http%3A%2F%2Flocalhost%3A8080&client_id=034xxxx9-9xx8-4xxf-bexx-1bc5xxxxbd0c&response_type=code
or removed all the "-" in client id
http://('https//login.microsoftonline.com/common/oauth2/authorize',)?redirect_uri=http%3A%2F%2Flocalhost%3A8080&client_id=034xxxx99xx84xxfbexx1bc5xxxxbd0c&response_type=code
Either way, I got the same result, IE did not show the popup with a line "This page can’t be displayed"

Pyramid authentication: Why does it work?

I'm just now getting into authentication in my app, and all of the pyramid examples that I can find explain the straightforward parts very well, but handwave over the parts that don't make any sense to me.
Most of the examples look something like this:
login = request.params['login']
password = request.params['password']
if USERS.get(login) == password:
headers = remember(request, login)
return HTTPFound(location = came_from,
headers = headers)
And from init:
session_factory = UnencryptedCookieSessionFactoryConfig(
settings['session.secret']
)
authn_policy = SessionAuthenticationPolicy()
authz_policy = ACLAuthorizationPolicy()
Trying to track down the point in which the login actually happens, I'm assuming it's this one:
headers = remember(request, login)
It appears to me that what is going on is we're storing the username in the session cookie.
If I put this line in my app, the current user is magically logged in, but why?
How does pyramid know that I'm passing a username? It looks like I'm just passing the value of login. Further, this variable is named differently in different examples.
Even if it does know that it's a username, how does it connect it with the user ID? If I run authenticated_userid(request) afterwards, it works, but how has the system connected the username with the userid? I don't see any queries as part of the remember() documentation.
Pyramid's security system revolves around principals; your login value is that principal. It is up to your code to provide remember() with a valid principal name; if your login name filled in the form is used as your principal, then that's great. If you are using an email address but use a database primary key as the principal string, then you'd have to map that yourself.
What exactly remember() does depends on your authentication policy; it is up to the policy to 'know' from request to request what principal you asked it to remember.
If you are using the AuthTktAuthenticationPolicy policy, then the principal value is stored in a cryptographically signed cookie; your next response will have a Set-Cookie header added. Then next time a request comes in with that cookie, provided it is still valid and the signature checks out, the policy now 'knows' what principle is making that request.
When that request then tries to access a protected resource, Pyramid sees that a policy is in effect, and asks that policy for the current authenticated principle.

Get access token for Soundcloud desktop application?

Toying around with Soundclouds SDK for Python with an impact of TKinter as GUI. Now I want to generate a access token for each user so that I could access more API-endpoints.
I have created an applicaton in Soundclouds Developer portal with a link to my callback.
There is nothing corresponding to generating a access token for an desktop application. Only for server-side application. I tried this code below:
import soundcloud
# create client object with app credentials
client = soundcloud.Client(client_id='YOUR_CLIENT_ID',
client_secret='YOUR_CLIENT_SECRET',
redirect_uri='REDIRECT_URL')
# redirect user to authorize URL
redirect client.authorize_url()
I have set my keys, and redirect_uri as the callback on my webserver. When I run my python file from the terminal, I get this:
File "token.py", line 9
redirect client.authorize_url()
^
SyntaxError: invalid syntax
Using Python 2.7.5+
What is causing this? I want to generete my access token and print in later on.
The solution might be that I need to create an instance of an web browser window, make the user accept the app using Soundcloud connect. The I grab the url and sort out the "code" in the url. Exchanges the code against an access-token and stores it inside a text-file. So that I could grab it later on.
A simple way of obtaining an access token is by first authenticating via the User Credentials flow, which exchanges your username and password for an access token:
client = soundcloud.Client(client_id = 'CLIENT_ID',
client_secret = 'CLIENT_SECRET',
username = 'USERNAME',
password = 'PASSWORD')
print client.access_token
try:
redirect(client.authorize_url())

Categories