How to get ArcGIS API for Python to connect to an ArcGIS Online account with federated credentials and no password prompt

6104
3
08-05-2019 08:11 AM
AndrewRudin1
Frequent Contributor

I am a GIS professional within my organization. I'm trying to write a python script that can access our ArcGIS Online organization to help me automate management the layers and other items I'm responsible for.  Some of these layers are not shared publicly and are restricted by groups within the org.  I login into our organization with an account federated with our Active Directory.  I want the script I'm writing to run at night and obtain info from all my items, so it can't prompt me for a password at runtime.

I'm following the instructions in the API help (link here) for how to connect, but I'm running into issues.  Specifically I'm using the sample code from the section after the paragraph:

"If the configured identity provider is compatible, you may also be able to provide your username and password, along with the client_id for a non interactive login experience using OAuth 2.0, as shown below:"

I have Pro 2.4 installed, and I'm using a python environment that has the ArcGIS API for python upgraded to 1.6.2.

Here is my code:

import arcgis

gis = arcgis.GIS("https://myagolorg.maps.arcgis.com", username="MyActiveDirectoryUsername", password="MyActiveDirectoryPassword", client_id='MyAGOLAppClientID')

print("Successfully logged in as: " + gis.properties.user.username)

When I run this in a Jupyter Notebook, I get a 'module not found error'.  

ModuleNotFoundError: No module named 'bs4'

I googled bs4 and figured out it's a module named BeautifulSoup4.  I went back into Pro and added that package to my environment 

After this install is done I rerun by script, but now I get a variable reference error: 

UnboundLocalError: local variable 'oauth_info' referenced before assignment

Has anyone been able to successfully login to their AGOL org from python API using a federated account and no credentials prompt?  If there is another method let me know.  I know that a built-in account would be easier but that's not my preference.  I know that an app login my work for connecting, but it won't provide access to items that aren't shared publicly.

Thank you, 

3 Replies
RohitSingh2
Esri Contributor

OAuth2/SAML is an interactive workflow and we do not know what identity provider may be configured and how it prompts the user to sign in.

 

We have some special logic to handle non-interactive login given the username and password if the configured identify provider is a particular one and responds to our requests with a known format. This is the identity provider configured on our Python API demo portal (python.playground.esri.com) and a few other Esri portals. The approach we use to login non-interactly on such portals is similar to the one described at https://www.prowestgis.com/there-and-back-again/.

 

However, it’s more likely that we wont encounter such portals in the wild and we fall back to interactive login if that is the case. This is what you are experiencing.

 

The recommended suggestion for non-interactive login for scripts is to use built-in users instead of SAML.

0 Kudos
JohnMDye
Frequent Contributor

@RohitSingh2 I'm running into a similar problem. While your answer above is good and understandable, I'd offer that if Esri is going to require bs4, the least they can do is make it part of the default Pro env so that I don't have to clone and create a new env, then set it as the default env, just to use a documented feature that should "just work"

0 Kudos
GeofyAdmin
Occasional Contributor

Rohit’s answer is very comprehensive and the solution to use named user from the agol store is appropriate but just in case you wanted to run the script as the actual end use, one way is to bypass the problem you are facing by:

1. Use a web workflow first through the JS API to authenticate the end user with OAuth Federated identity and grab the user token

2. Pass that token down (through a secured web service) to your python script and create the GIS object using token auth

Obviously the token has an expiry time. 

Also, the web service above should be secure and posted on https. 

I’ve used this before successfully. 

Good luck.