How to access a sharepoint site via the REST API in Python? - python

I have the following site in SharePoint 2013 in my local VM:
http://win-5a8pp4v402g/sharepoint_test/site_1/
When I access this from the browser, it prompts me for the username and password and then works fine. However I am trying to do the same using the REST API in Python. I am using the requests library, and this is what I have done:
import requests
from requests.auth import HTTPBasicAuth
USERNAME = "Administrator"
PASSWORD = "password"
response = requests.get("http://win-5a8pp4v402g/sharepoint_test/site_1/", auth=HTTPBasicAuth(USERNAME, PASSWORD))
print response.status_code
However I get a 401. I dont understand. What am I missing?
Note: I followed this article http://tech.bool.se/using-python-to-request-data-from-sharepoint-via-rest/

It's possible that your SharePoint site uses a different authentication scheme. You can check this by inspecting the network traffic in Firebug or the Chrome Developer Tools.
Luckily, the requests library supports many authentication options: http://docs.python-requests.org/en/latest/user/authentication/
Fore example, one of the networks I needed to access uses NTLM authentication. After installing the requests-ntml plugin, I was able to access the site using code similar to this:
import requests
from requests_ntlm import HttpNtlmAuth
requests.get("http://sharepoint-site.com", auth=HttpNtlmAuth('DOMAIN\\USERNAME','PASSWORD'))

Here is an examples of SharePoint 2016 REST API call from Python to create a site.
import requests,json,urllib
from requests_ntlm import HttpNtlmAuth
root_url = "https://sharepoint.mycompany.com"
headers = {'accept': "application/json;odata=verbose","content-type": "application/json;odata=verbose"}
##"DOMAIN\username",password
auth = HttpNtlmAuth("MYCOMPANY"+"\\"+"UserName",'Password')
def getToken():
contextinfo_api = root_url+"/_api/contextinfo"
response = requests.post(contextinfo_api, auth=auth,headers=headers)
response = json.loads(response.text)
digest_value = response['d']['GetContextWebInformation']['FormDigestValue']
return digest_value
def createSite(title,url,desc):
create_api = root_url+"/_api/web/webinfos/add"
payload = {'parameters': {
'__metadata': {'type': 'SP.WebInfoCreationInformation' },
'Url': url,
'Title': title,
'Description': desc,
'Language':1033,
'WebTemplate':'STS#0',
'UseUniquePermissions':True}
}
response = requests.post(create_api, auth=auth,headers=headers,data=json.dumps(payload))
return json.loads(response.text)
headers['X-RequestDigest']=getToken()
print createSite("Human Resources","hr","Sample Description")

You can also use Office365-REST-Python-Client ("Office 365 & Microsoft Graph Library for Python") or sharepoint ("Module and command-line utility to get data out of SharePoint")

A 401 response is an authentication error...
That leaves one of your three variables as incorrect: url, user, pass. Requests Authentication Docs
Your url looks incomplete.

Related

how to use python to authenticate using okta and perform an action

I have a web portal, it uses okta for user authentication.
I need to write a python script and perform a post operation on the portal app.
I tried using requests python library
#! /usr/bin/env python
import requests
s= requests.session()
login_data = {'username':'XXXXXX', 'password': 'XXXXXXXX'}
r = s.post('https://example.okta.com/login/login.htm', login_data)
#print(r.cookies)
data = {"type": "live"}
r2 = s.post('https://example.com/merchant', data=data)
This doesn't seem to work, I not getting a session created and not seeing the post happening on the portal

WebLogin not successful using requests in python

I am trying to login to the following web address: http://healthifyme.com/login/
using requests. I intend to scrap data from http://healthifyme.com/dashboard after login.
I am using following code to login using my registered credentials but login is not successful:
import requests, lxml.html
from lxml import html
url = 'http://healthifyme.com/login/'
s = requests.Session()
payload = {
'email': 'myemail#gmail.com',
'password': 'mypassword'
}
r = s.post(url, data=payload)
What I may be missing that's preventing the login attempt?
After 1 login attempt on the linked site, I noticed that the username and password are posted in a JSON object, instead of a form-like encoding like in the OP. Luckily that is excessibely simple with requests. You should simply use the json param to .post():
r = s.post(url, json=payload)

Python Requests - authentication after redirect

I have a quick question regarding HTTP Basic Authentication after a redirect.
I am trying to login to a website which, for operational reasons, immediately redirects me to a central login site using an HTTP 302 response. In my testing, it appears that the Requests module does not send my credentials to the central login site after the redirect. As seen in the code snippet below, I am forced to extract the redirect URL from the response object and attempt the login again.
My question is simply this:
is there a way to force Requests to re-send login credentials after a redirect off-host?
For portability reasons, I would prefer not to use a .netrc file. Also, the provider of the website has made url_login static but has made no such claim about url_redirect.
Thanks for your time!
CODE SNIPPET
import requests
url_login = '<url_login>'
myauth = ('<username>', '<password')
login1 = requests.request('get', url_login, auth=myauth)
# this login fails; response object contains the login form information
url_redirect = login1.url
login2 = requests.request('get', url_redirect, auth=myauth)
# this login succeeds; response object contains a welcome message
UPDATE
Here is a more specific version of the general code above.
The first request() returns an HTTP 200 response and has the form information in its text field.
The second request() returns an HTTP 401 response with 'HTTP Basic: Access denied.' in its text field.
(Of course, the login succeeds when provided with valid credentials.)
Again, I am wondering whether I can achieve my desired login with only one call to requests.request().
import requests
url_login = 'http://cddis-basin.gsfc.nasa.gov/CDDIS_FileUpload/login'
myauth = ('<username>', '<password>')
with requests.session() as s:
login1 = s.request('get', url_login, auth=myauth)
url_earthdata = login1.url
login2 = s.request('get', url_earthdata, auth=myauth)
My solution to this would be use of "Session". Here is how you can implement Session.
import requests
s = requests.session()
url_login = "<loginUrl>"
payload = {
"username": "<user>",
"password": "<pass>"
}
req1 = s.post(url_login, data=payload)
# Now to make sure you do not get the "Access denied", use the same session variable for the request.
req2 = s.get(url_earthdata)
This should solve your problem.
This isn't possible with Requests, by design. The issue stems from a security vulnerability, where if an attacker modifies the redirect URL and the credentials are automatically sent to the redirect URL, then the credentials are compromised. So, credentials are stripped from redirect calls.
There's a thread about this on github:
https://github.com/psf/requests/issues/2949

Handling windows authentication while accessing url using requests

I am using python request library to access the soap requests. And it was working fine. As there is change in our domain structure. I could not access the url, it always prompting me to enter the credentials.
I am using below code to access the url earlier using requests.
program_list_response = requests.get(program_list_path,
data=self.body, headers=self.headers)
How to pass the authentication in background using requests?
You can use the Authentication feature for that in order to provide the credentials for the link that you want to access.
For an eg:
You can pass the username and password by using the below format:
requests.get('https://website.com/user', auth=('user', 'pass'))
For more details I would recommend the official docs.
For handling the Windows authentication then I would recommend the Requests-NTLM.
For eg:
import requests
from requests_ntlm import HttpNtlmAuth
requests.get("http://ntlm_protected_site.com",auth=HttpNtlmAuth('domain\\username','password'))

Unable to retain login credentials across pages while using requests

I am pretty new to using urllib and requests module in python. I am trying to access a wikipage in my company's website which requires me to provide my login credentials through a pop up window when I try to access it through a browser.
I was able to write the following script to successfully access the webpage and read it using the following piece of code:
import sys
import urllib.parse
import urllib.request
import getpass
import http.cookiejar
wiki_page = 'http://wiki.company.com/wiki_page'
top_level_url = 'http://login.company.com/'
username = input("Enter Username: ")
password = getpass.getpass('Enter Password: ')
# Authenticate with login server and fetch the wiki page
password_mgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()
cj = http.cookiejar.CookieJar()
password_mgr.add_password(None, top_level_url, username, password)
handler = urllib.request.HTTPBasicAuthHandler(password_mgr)
opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj),handler)
opener.open(wiki_page)
urllib.request.install_opener(opener)
with urllib.request.urlopen(wiki_page) as response:
# Do something
But now I need to use requests module to do the same. I tried using several methods including sessions but could not get it to work. The following is the piece of code which I think close to the actual solution but it gives Response 200 in the first print and Response 401 in the second print:
s = requests.Session()
print(s.post('http://login.company.com/', auth=(username, password))) # I have tried s.post() as well as s.get() in this line
print(s.get('http://wiki.company.com/wiki_page'))
The site uses the Basic Auth authorization scheme; you'll need to send the login credentials with each request.
Set the Session.auth attribute to a tuple with the username and password on the session:
s = requests.Session()
s.auth = (username, password)
response = s.get('http://wiki.company.com/wiki_page')
print(response.text)
The urllib.request.HTTPPasswordMgrWithDefaultRealm() object would normally only respond to challenges on URLs that start with http://login.company.com/ (so any deeper path will do too), and not send the password elsewhere.
If the simple approach (setting Session.auth) doesn't work, you'll need to find out what response is returned by accessing http://wiki.company.com/wiki_page directly, which is what your original code does. If the server redirects you to a login page, where you then use the Basic Auth information, you can replicate that:
s = requests.Session()
response = s.get('http://wiki.company.com/wiki_page', allow_redirects=False)
if response.status_code in (302, 303):
target = response.headers['location']
authenticated = s.get(target, auth=(username, password))
# continue on to the wiki again
response = s.get('http://wiki.company.com/wiki_page')
You'll have to investigate carefully what responses you get from the server. Open up an interactive console and see what responses you get back. Look at response.status_code and response.headers and response.text for hints. If you leave allow_redirects to the default True, look at response.history to see if there were any intermediate redirections.

Categories