Our ArcGIS Server 10.31 uses Integrated Windows Authentication (IWA). I am able to access everything using a web browser without ever logging in. It's really seamless. The problem I'm having is getting some Python code to access the REST admin URLs (using urllib, requests, or similar), e.g.:
http://[domain]/arcgis/admin/security/users/search
When Python runs, it doesn't take advantage of the Integrated Windows Authentication. The response I get is a 401 with the body HTML saying:
401 - Unauthorized: Access is denied due to invalid credentials. You do not have permission to view this directory or page using the credentials that you supplied.
I have tried just about every iteration of passing in POST parameters, headers, and cookies with the python urllib and requests modules. I have tried passing in my user/pass, a token I generated, and also tokens that I fish out of Firefox's request/response stream. I may not have exhausted every possible combination, but I've given it the good ole' college try and come up empty. If anyone knows how to access the REST Admin URLs from Python (under IWA), I'd appreciate the help.
Another thought I had is that tokens and logins are going about this the wrong way. Is there some way to get Python to use my IWA identity and run as me, just like Firefox and Internet Explorer do? That could be a more elegant solution, since I wouldn't have to fool around with generating tokens or sending a user/pass around.
Thanks!
Solved! Go to Solution.
If you can get away with it, I would recommend using the python api.
https://developers.arcgis.com/python/
Otherwise, I would use portalpy.
https://enterprise.arcgis.com/en/portal/latest/administer/windows/portalpy-module.htm
If none of the above can get it done, then yes, you will need to delve into requests, encoding etc.
I had never heard of portalpy. I found it, but the page says it's been deprecated.
PortalPy: GitHub - Esri/portalpy: A module that allows you to administer Portal for ArcGIS and ArcGIS Online.
Here is how I solved it (kind of). I have to give it a user/pass, which means I need to either enter that every time it runs (can't be automated) or store it somewhere in a file on my computer (questionable security practice). The good news is I don't have to fool around with tokens.
Since I don't specify anything that when connecting with a browser, I feel like this is still sub-optimal. Does anyone know how to get Python to run as my user without me having to enter my user/password? Internet Explorer works with ArcGIS Server natively. I had to explicitly tell Firefox to trust my org's domain in order to activate Integrated Windows Authentication. Is there something like that for Python?
Without further ado, here is how I (kind of) solved this:
import json import requests from requests_ntlm import HttpNtlmAuth server_root = 'http://your_domain/arcgis/admin/ ' role_url = server_root + 'security/roles/getUsersWithinRole' role_name = 'your_role' ntlm_user = 'your_user' ntlm_pass = 'your_password' params = {'rolename': role_name, 'f': 'pjson'} ehp_users_response = requests.post( role_url, data=params, auth=HttpNtlmAuth(ntlm_user, ntlm_pass))
That did it, thanks!!! No user/pass needed.
With the code above, add this import:
from requests_negotiate_sspi import HttpNegotiateAuth
Then, update the requests.post with the following code:
ehp_users_response = requests.post( role_url, data=params, auth=HttpNegotiateAuth())
Glad it worked for you. I had a similar question a while back and was surprised to find how it wasn't more baked into Requests itself.