Problems with Python script tryng to access my company AD FS internal server (Active Directory Federation Services)

Hi everyone,

I try to create a python script to access my company AD FS server. This ADFS service is crucial to gain a Token to permit script to consume Microsft Dynamics 365 web services ( with authorization bearer token on request header). I find a python package that microsoft created for that kind of purpose: https://pypi.org/project/adal/

I install this package, and all relative dependencies, on Ignition folder:

Inductive Automation\Ignition\user-lib\pylib

Ignition server is 8.0.2 version.

Here my final script code:

import json
import logging
import adal

def turn_on_logging():
    logging.basicConfig(level=logging.DEBUG)
    #or,
    #handler = logging.StreamHandler()
    #adal.set_logging_options({
    #    'level': 'DEBUG',
    #    'handler': handler
    #})
    #handler.setFormatter(logging.Formatter(logging.BASIC_FORMAT))
    
#uncomment for verbose log
print('start logging')
turn_on_logging()


authority_url = "https://myadfsinternalserver/adfs"
activeDirectoryResource = "myResource"
clientId = "myClientID"
clientSecret = "mySecret"


### Main logic begins
auth_context = adal.AuthenticationContext(
    authority_url, 
    validate_authority=False,
    api_version=None,
    timeout = (1000000, 1000000),
    verify_ssl=False
)

print('DONE: create context')


token = auth_context.acquire_token_with_client_credentials(
	activeDirectoryResource,
	clientId,
	clientSecret
)
### Main logic ends

print('DONE: context acquire_token')

print('Here is the token:')
print(json.dumps(token, indent=2))

When I run script I give this error:

Jython 2.7.1 (default:0df7adb1b397, Jun 30 2017, 19:02:43) 
[OpenJDK 64-Bit Server VM (Azul Systems, Inc.)] on java11.0.3

>>> 
start logging
DONE: create context
DEBUG:adal-python:259961c6-e431-4d47-bf0a-7b1d093047ed - Authority:Instance discovery/validation has either already been completed or is turned off: ...
INFO:adal-python:259961c6-e431-4d47-bf0a-7b1d093047ed - TokenRequest:Getting token with client credentials.
DEBUG:adal-python:259961c6-e431-4d47-bf0a-7b1d093047ed - TokenRequest:No user_id passed for cache query
DEBUG:adal-python:259961c6-e431-4d47-bf0a-7b1d093047ed - CacheDriver:finding with query keys: {'_clientId': '...'}
DEBUG:adal-python:259961c6-e431-4d47-bf0a-7b1d093047ed - CacheDriver:Looking for potential cache entries: {'_clientId': '...'}
DEBUG:adal-python:259961c6-e431-4d47-bf0a-7b1d093047ed - CacheDriver:Found 0 potential entries.
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): myadfsinternalserver:443
ERROR:adal-python:259961c6-e431-4d47-bf0a-7b1d093047ed - OAuth2Client:Get Token request failed
Traceback (most recent call last):
  File "C:\Users\garzon_r\.ignition\cache\gw192.168.200.112_8088\C0\pylib\adal\oauth2_client.py", line 263, in get_token
    resp = requests.post(token_url.geturl(),
  File "C:\Users\garzon_r\.ignition\cache\gw192.168.200.112_8088\C0\pylib\requests\api.py", line 116, in post
    return request('post', url, data=data, json=json, **kwargs)
  File "C:\Users\garzon_r\.ignition\cache\gw192.168.200.112_8088\C0\pylib\requests\api.py", line 60, in request
    return session.request(method=method, url=url, **kwargs)
  File "C:\Users\garzon_r\.ignition\cache\gw192.168.200.112_8088\C0\pylib\requests\sessions.py", line 533, in request
    resp = self.send(prep, **send_kwargs)
  File "C:\Users\garzon_r\.ignition\cache\gw192.168.200.112_8088\C0\pylib\requests\sessions.py", line 646, in send
    r = adapter.send(request, **kwargs)
  File "C:\Users\garzon_r\.ignition\cache\gw192.168.200.112_8088\C0\pylib\requests\adapters.py", line 498, in send
    raise ConnectionError(err, request=request)
ConnectionError: ('Connection aborted.', error(10054, 'Socket closed'))

I think there something related with HTTPS and/or Certificate, ecc…

I try this script on a separate python (versione 2.7.x ) stand alone project and everything works fine…

Somebody else have experience with that kind of error or with “adal” package or how to deep trubleshotting ???

Many thanks

My first step in troubleshooting would be to look at the python version. When you’re testing with a separate python stand alone project, are you testing with Jython 2.7.1? If not, can you try it? (That’s the version that Ignition 8.0 ships with.) If it doesn’t work with that, it might be a Jython issue. If it does work with it, it certainly could be a cert / ssl issue.

If you need Jython 2.7.1, you can download it here: https://jython.github.io/download

Upon digging a little deeper, it appears adal depends on the python module “cryptography”, which has c dependencies (both internally and in its own dependency “cffi”). This means it probably won’t run in Jython. Unencrypted calls might work, but I don’t think any https calls will be successful.

1 Like

Hi Kevin,
thank you very much for your reply.

The answer for your first question

I create a stand alone project on my Python IDE ( PyCharm ) with 2.7.x python interpreter, and with pip, I installed “adal” package. After I run scritpt and here the return code:

start logging
DEBUG:adal-python:3fa7aa3d-3a58-4910-a969-bc826347f9ca - Authority:Instance discovery/validation has either already been completed or is turned off: ...
DONE: create context
INFO:adal-python:3fa7aa3d-3a58-4910-a969-bc826347f9ca - TokenRequest:Getting token with client credentials.
DEBUG:adal-python:3fa7aa3d-3a58-4910-a969-bc826347f9ca - TokenRequest:No user_id passed for cache query
DEBUG:adal-python:3fa7aa3d-3a58-4910-a969-bc826347f9ca - CacheDriver:finding with query keys: {'_clientId': '...'}
DEBUG:adal-python:3fa7aa3d-3a58-4910-a969-bc826347f9ca - CacheDriver:Looking for potential cache entries: {'_clientId': '...'}
DEBUG:adal-python:3fa7aa3d-3a58-4910-a969-bc826347f9ca - CacheDriver:Found 0 potential entries.
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): myadfsinternalserver:443
DEBUG:urllib3.connectionpool:myadfsinternalserver:443 "POST /adfs/oauth2/token HTTP/1.1" 200 942
INFO:adal-python:3fa7aa3d-3a58-4910-a969-bc826347f9ca - OAuth2Client:Get Token Server returned this correlation_id: 3fa7aa3d-3a58-4910-a969-bc826347f9ca
DONE: context acquire_token
Here is the token:
DEBUG:adal-python:3fa7aa3d-3a58-4910-a969-bc826347f9ca - CacheDriver:Adding entry AccessTokenId: TyX6ME4qM8APX52HVM+4ouexaXsCLtESQV+6PvrJU5c=
{
  "expiresIn": 3600, 
  "_authority": "https://myadfsserver/adfs", 
  "resource": "MyResource", 
  "tokenType": "bearer", 
  "expiresOn": "2019-06-18 12:40:39.434000", 
  "_clientId": "6b6cd25d-d89f-4be2-814c-36678fdf2d61", 
  "accessToken": "eyJ0eXAiOiJ---------------------u1wWhDH8R2UVGik06U1IZoA"
}

Process finished with exit code 0

For your second reply do you know if exist another alternative to use to accomplish for adfs server connection ???

Thank you very much

You have to get creative to work around the Python/Jython version limitations.
In our case, we have had built stand-alone RESTful endpoints (outside of Ignition, optionally in a docker container) that would process a request from Ignition, perform the authentication, and return the token to be consumed by your script.

This isn't a good test, unfortunately, unless you specifically installed a Jython interpreter into Pycharm (see this link), Pycharm is using CPython 2.7. The versions are the same, but the actual language is fundamentally different, because CPython is, as the name implies, backed by C, which means it can use libraries that aren't compatible with other Python distributions (IPython, PyPi, Jython, etc).