# Download document from SharePoint (NTLM Authentication)

**URL:** <https://forum.inductiveautomation.com/t/download-document-from-sharepoint-ntlm-authentication/69474>\
**Category:** Ignition\
**Tags:** python, scripting\
**Created:** [February 6, 2023, 10:50am UTC](https://forum.inductiveautomation.com/t/download-document-from-sharepoint-ntlm-authentication/69474 "2023-02-06T10:50:55Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Matthew\_Farmer](https://avatars.discourse-cdn.com/v4/letter/m/e274bd/32.png) [@Matthew\_Farmer](https://forum.inductiveautomation.com/u/Matthew_Farmer)\
**Post date:** [February 6, 2023, 10:50am UTC](https://forum.inductiveautomation.com/t/download-document-from-sharepoint-ntlm-authentication/69474/1 "2023-02-06T10:50:55Z")

</div>

I am trying to download a document from an (Old) SharePoint library in a Jython script. When I attempt to open the document with either "requests.Get" or "system.net.httpGet" I get 401 (Unauthorized).  
I believe the reason for this is that I need to use NTLM authentication because the HTTP response contains:  
'WWW-Authenticate': 'NTLM'

As far as I can tell there is no way to specify NTLM authentication header in the version of these libraries found in Ignition, does anyone have any ideas?

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [February 6, 2023, 5:32pm UTC](https://forum.inductiveautomation.com/t/download-document-from-sharepoint-ntlm-authentication/69474/2 "2023-02-06T17:32:45Z")

</div>

You're correct, there's no built-in ways to do this in Ignition. You have a couple options; you could attempt to assemble the right authentication header yourself, but as far as I understand NTLM it requires a few roundtrips, so it's a bit involved.  
You might be able to extend `requests`, if you've already got it installed, with the `requests-ntlm` module:

> **[GitHub - requests/requests-ntlm: NTLM authentication support for Requests.](https://github.com/requests/requests-ntlm)**
>
> NTLM authentication support for Requests. Contribute to requests/requests-ntlm development by creating an account on GitHub.

I have **no** idea if it will work in Jython's environment or not.  
You could also create a module (or drop in one or more .jar files in the appropriate location) that exposes _Java_ library code to create an NTLM client connection.

---

<div class="post-metadata">

**Author:** ![Matthew.gaitan](https://avatars.discourse-cdn.com/v4/letter/m/59ef9b/32.png) [@Matthew.gaitan](https://forum.inductiveautomation.com/u/Matthew.gaitan)\
**Post date:** [February 6, 2023, 6:16pm UTC](https://forum.inductiveautomation.com/t/download-document-from-sharepoint-ntlm-authentication/69474/3 "2023-02-06T18:16:40Z")

</div>

> [@Webservices NTLM Auth](https://forum.inductiveautomation.com/t/webservices-ntlm-auth/12656/9):
>
> After some playing around I was able to setup a basic HTTP GET using Java and supplying NTLM auth. However, I am finding that I am getting import errors in the Gateway Scope, but not in the Designer scope. I am running the same Java (8.231) on both designer and gateway, is there some odd difference in context of why the below might fail? # Perform a basic HTTP Get to the provided URL using the NTLM auth in the function def \_httpGetNTLM(url): from org.apache.http.auth import AuthScope from …

I've been using this successfully for a couple of months to get our ArcGIS data into perspective with no issues

---

<div class="post-metadata">

**Author:** ![Matthew\_Farmer](https://avatars.discourse-cdn.com/v4/letter/m/e274bd/32.png) [@Matthew\_Farmer](https://forum.inductiveautomation.com/u/Matthew_Farmer)\
**Post date:** [February 7, 2023, 7:57am UTC](https://forum.inductiveautomation.com/t/download-document-from-sharepoint-ntlm-authentication/69474/4 "2023-02-07T07:57:31Z")

</div>

@paul-griffith  
PIP install requests-ntlm fails to install so that looks like a dead end

@Matthew.gaitan  
I copied the code on the thread you shared and I got a success code straight away!.. But I don't know how to actually download the file as the line `content = BasicResponseHandler().handleResponse(response)` returns a string, but the file I am downloading is an .xls so I need to access it as binary file, not plain text.  
I tried using `response.getEntity().getContent()` but this returns an 'org.apache.http.conn.EofSensorInputStream' but I don't know how to convert that to a byte stream Python can read.

---

<div class="post-metadata">

**Author:** ![Matthew\_Farmer](https://avatars.discourse-cdn.com/v4/letter/m/e274bd/32.png) [@Matthew\_Farmer](https://forum.inductiveautomation.com/u/Matthew_Farmer)\
**Post date:** [February 10, 2023, 11:05am UTC](https://forum.inductiveautomation.com/t/download-document-from-sharepoint-ntlm-authentication/69474/5 "2023-02-10T11:05:18Z")

</div>

@Matthew.gaitan Any ideas on how to get a binary stream instead of a plain text stream?

---

<div class="post-metadata">

**Author:** ![Matthew.gaitan](https://avatars.discourse-cdn.com/v4/letter/m/59ef9b/32.png) [@Matthew.gaitan](https://forum.inductiveautomation.com/u/Matthew.gaitan)\
**Post date:** [February 10, 2023, 3:46pm UTC](https://forum.inductiveautomation.com/t/download-document-from-sharepoint-ntlm-authentication/69474/6 "2023-02-10T15:46:23Z")

</div>

Not sure, sorry. I've (thankfully) never had to deal with sharepoint integrations via ignition.

After a quick google search:

> <https://stackoverflow.com/questions/5015598/how-can-i-read-a-bytearray-from-an-httpresponse>

I would try the first response using `EntityUtils.toByteArray`

with an import statement of `from org.apache.http.util import EntityUtils`

No clue if this will actually work though

---

<div class="post-metadata">

**Author:** ![ryanjmclaughlin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ryanjmclaughlin/32/4318_2.png) [@ryanjmclaughlin](https://forum.inductiveautomation.com/u/ryanjmclaughlin)\
**Post date:** [February 11, 2023, 11:04pm UTC](https://forum.inductiveautomation.com/t/download-document-from-sharepoint-ntlm-authentication/69474/7 "2023-02-11T23:04:56Z")

</div>

Here is what I use, can work for files just need to modify the return...

```auto
def httpGetNTLM(url):
	from org.apache.http.auth import AuthScope
	from org.apache.http.auth import NTCredentials
	from org.apache.http.client.methods import HttpGet
	from org.apache.http.impl.client import DefaultHttpClient
	from org.apache.http.impl.client import BasicResponseHandler
	from org.apache.http.entity import ContentType
	from java.io import ByteArrayOutputStream
	
	# Setup the client with NTLM Auth
	httpclient = DefaultHttpClient()
	
	# Define the credentials to use
	creds = NTCredentials(username, password, system.net.getHostName(), "DOMAIN")
	httpclient.getCredentialsProvider().setCredentials(AuthScope.ANY, creds)
	
	# Define the host and URL to call
	httpget = HttpGet(url)
	
	# Execute the request
	response = httpclient.execute(httpget)
	
	# Get response entity and MIME type
	entity = response.getEntity()
	contentType = ContentType.getOrDefault(response.getEntity()).getMimeType().lower()
	
	# Return the result
	if 'json' in contentType:
		return system.util.jsonDecode(BasicResponseHandler().handleResponse(response))
	elif contentType in ["image/png", "image/jpeg"]:
		baos = ByteArrayOutputStream()
		entity.writeTo(baos)
		return baos.toByteArray(), contentType
	else:
		return BasicResponseHandler().handleResponse(response), contentType

```

---

<div class="post-metadata">

**Author:** ![Matthew\_Farmer](https://avatars.discourse-cdn.com/v4/letter/m/e274bd/32.png) [@Matthew\_Farmer](https://forum.inductiveautomation.com/u/Matthew_Farmer)\
**Post date:** [February 13, 2023, 3:44pm UTC](https://forum.inductiveautomation.com/t/download-document-from-sharepoint-ntlm-authentication/69474/8 "2023-02-13T15:44:38Z")

</div>

Thanks @Matthew.gaitan that was the last part I needed

My final code:

```auto
# Perform a basic HTTP Get to the provided URL using the NTLM auth in the function
def DownloadFile(remoteFile, localFile):	
	from org.apache.http.auth import AuthScope
	from org.apache.http.auth import NTCredentials
	from org.apache.http.client.methods import HttpGet
	from org.apache.http.impl.client import DefaultHttpClient
	from org.apache.http.impl.client import BasicResponseHandler
	from org.apache.http.entity import ContentType
	from org.apache.http.util import EntityUtils
	
	# Setup the client with NTLM Auth
	httpclient = DefaultHttpClient()
	
	# Define the credentials to use
	creds = NTCredentials(username, password, system.net.getHostName(), domain)
	httpclient.getCredentialsProvider().setCredentials(AuthScope.ANY, creds)
	
	# Define the host and URL to call
	httpget = HttpGet(remoteFile)
	
	# Execute the request
	response = httpclient.execute(httpget)
	
	# Copy the file
	with open(localFile, "wb") as output_file:
		output_file.write(EntityUtils.toByteArray(response.getEntity()))

```
