# \[IGN-4258\]Digest auth with httpClient

**URL:** <https://forum.inductiveautomation.com/t/ign-4258-digest-auth-with-httpclient/66137>\
**Category:** Ignition\
**Tags:** ignition81\
**Created:** [November 4, 2022, 4:08pm UTC](https://forum.inductiveautomation.com/t/ign-4258-digest-auth-with-httpclient/66137 "2022-11-04T16:08:48Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![louagejasper](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/louagejasper/32/86311_2.png) [@louagejasper](https://forum.inductiveautomation.com/u/louagejasper)\
**Post date:** [November 4, 2022, 4:08pm UTC](https://forum.inductiveautomation.com/t/ign-4258-digest-auth-with-httpclient/66137/1 "2022-11-04T16:08:48Z")

</div>

Hi,

Has anyone done a http request using digest auth as authentication method?  
I've tried using httpClient(), but without any results. Would be super nice if someone could share some knowledge/code on this.

---

<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:** [November 4, 2022, 4:30pm UTC](https://forum.inductiveautomation.com/t/ign-4258-digest-auth-with-httpclient/66137/2 "2022-11-04T16:30:37Z")

</div>

This'll probably be tricky to do from client code, although if you have a fixed target you might be able to manually encode the right authorization headers. It depends on which form of digest auth the server is expecting; more modern forms pass a `nonce` back to an initial request, so you'd have to issue multiple requests to properly authenticate.

We have plans to support this directly, but no timeline.

---

<div class="post-metadata">

**Author:** ![kcollins](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kcollins/32/19646_2.png) [@kcollins](https://forum.inductiveautomation.com/u/kcollins)\
**Post date:** [November 4, 2022, 5:06pm UTC](https://forum.inductiveautomation.com/t/ign-4258-digest-auth-with-httpclient/66137/3 "2022-11-04T17:06:26Z")

</div>

I recall having to create a module that would bring in [Apache HttpComponents/HttpClient](https://hc.apache.org/httpcomponents-client-5.1.x/) library to help facilitate Digest Auth interactions.. That was back in the 8.0 timeframe...

---

<div class="post-metadata">

**Author:** ![mweber1](https://avatars.discourse-cdn.com/v4/letter/m/e79b87/32.png) [@mweber1](https://forum.inductiveautomation.com/u/mweber1)\
**Post date:** [November 4, 2022, 5:15pm UTC](https://forum.inductiveautomation.com/t/ign-4258-digest-auth-with-httpclient/66137/4 "2022-11-04T17:15:48Z")

</div>

@kcollins is correct. We were trying to reach an HTTP client that uses Digest Auth in Ignition 7.9.8. At the time, we were not using any built-in system.http.x functions and were instead trying to use the urllib2 library. We kept bricking the test unit (fixed by reboot thankfully) because of a bug in urllib2 that failed to close one of the sockets on the digest auth chain and our unit can only handle 10 concurrent connections. We were polling for 26 tables worth of data (so 26 connections subsequently). Our way around it was to write an external module and use Apache HTTP outside of Jython 2.5. I think with newer versions of Ignition, you might be able to importurllib3 or even the [requests](https://requests.readthedocs.io/en/latest/) module to facilitate your needs.

If you aren't familiar with how Digest Auth works behind the scenes, I'd encourage a read. Summary, it opens a socket, sends the request without authentication information, gets the failure, then re-transmits the request with authentication. Each of those attempts should open (and close) it's socket on completion (successful or not).

I'd be happy to answer any other questions you might have. 🙂

---

<div class="post-metadata">

**Author:** ![louagejasper](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/louagejasper/32/86311_2.png) [@louagejasper](https://forum.inductiveautomation.com/u/louagejasper)\
**Post date:** [November 5, 2022, 7:18pm UTC](https://forum.inductiveautomation.com/t/ign-4258-digest-auth-with-httpclient/66137/5 "2022-11-05T19:18:43Z")

</div>

Thanks for the replies! So basically, there is no way without external libraries?

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [November 5, 2022, 8:01pm UTC](https://forum.inductiveautomation.com/t/ign-4258-digest-auth-with-httpclient/66137/6 "2022-11-05T20:01:22Z")

</div>

Have you examined the error response headers for the nonce you need? So you can compute the digest yourself?

---

<div class="post-metadata">

**Author:** ![louagejasper](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/louagejasper/32/86311_2.png) [@louagejasper](https://forum.inductiveautomation.com/u/louagejasper)\
**Post date:** [November 7, 2022, 7:37am UTC](https://forum.inductiveautomation.com/t/ign-4258-digest-auth-with-httpclient/66137/7 "2022-11-07T07:37:36Z")

</div>

I'll have to look into how to do that, but thanks for the idea. I'll check I can do that.

---

<div class="post-metadata">

**Author:** ![Stephen\_Troutner](https://avatars.discourse-cdn.com/v4/letter/s/cdc98d/32.png) [@Stephen\_Troutner](https://forum.inductiveautomation.com/u/Stephen_Troutner)\
**Post date:** [January 18, 2023, 3:26pm UTC](https://forum.inductiveautomation.com/t/ign-4258-digest-auth-with-httpclient/66137/8 "2023-01-18T15:26:17Z")

</div>

Did you end up figuring this out? I am working on a project that requires Digest Auth and I haven't found a way to do it in Ignition. I can read from the IO-Link device I am working without Digest Auth, but I haven't found a way to write the data I need since authentication is blocking me.

---

<div class="post-metadata">

**Author:** ![louagejasper](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/louagejasper/32/86311_2.png) [@louagejasper](https://forum.inductiveautomation.com/u/louagejasper)\
**Post date:** [January 18, 2023, 3:38pm UTC](https://forum.inductiveautomation.com/t/ign-4258-digest-auth-with-httpclient/66137/9 "2023-01-18T15:38:03Z")

</div>

I haven't found how to do it...

---

<div class="post-metadata">

**Author:** ![Travis.Cox](https://avatars.discourse-cdn.com/v4/letter/t/b9bd4f/32.png) [@Travis.Cox](https://forum.inductiveautomation.com/u/Travis.Cox)\
**Post date:** [October 8, 2024, 8:48pm UTC](https://forum.inductiveautomation.com/t/ign-4258-digest-auth-with-httpclient/66137/10 "2024-10-08T20:48:09Z")

</div>

Here is an example function:

```python
def getData(client, uri, url, username, password):
		import hashlib
		import random
		
		res = client.get(url)
		if res.statusCode == 401:
			headers = res.headers
			digestParts = headers["www-authenticate"][0].replace("Digest ", "").split(",")
			digestData = {}
			for part in digestParts:		
				partParts = part.strip().split("=")
				digestData[partParts[0]] = partParts[1].replace("\"", "")
			
			realm = digestData["realm"]
			charset = digestData["charset"]
			algorithm = digestData["algorithm"]
			nonce = digestData["nonce"]
			cnonce = "".join(random.choice("0123456789abcdef") for i in range(8))
			qop = digestData["qop"]
			nc = "00000001"
			
			ha1 = hashlib.md5("%s:%s:%s" % (username, realm, password)).hexdigest()
			ha2 = hashlib.md5("GET:%s" % (uri)).hexdigest()
			response = hashlib.md5("%s:%s:%s:%s:%s:%s" % (ha1, nonce, nc, cnonce, qop, ha2)).hexdigest()
			
			authorization = "Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", qop=%s, nc=%s, cnonce=\"%s\", response=\"%s\"" % (username, realm, nonce, uri, qop, nc, cnonce, response)
			res = client.get(url, headers={"Authorization":authorization})
		
		return res

```

You can call it like so:

```python
ipAddress = "192.168.10.10"
uri = "/path/to/call"
url = "https://%s%s" % (ipAddress, uri)
username = "admin"
password = "password"
client = system.net.httpClient(bypassCertValidation=True)
(authorization, res) = getData(client, uri, url, username, password)

```
