How to Generate Token By URL Request From ArcGIS Portal

15477
9
11-21-2017 02:05 PM
BehrouzHosseini
Occasional Contributor

I am able to create token from Generate Token operation on ArcGIS Portal Directory using IP Address of this request's origin parameter like enter image description here

but when I try to achive the token from URL like

https://map.geoca.com/portal/sharing/rest/generateToken?username=mapAdmin&password=psw&referer=https://map.geoca.com&f=json

I am getting this error message

{"error":{"code":405,"messageCode":"GWM_0005","message":"Method not supported.","details":[]}}

can you please let me know how I can fix this to get the token?

0 Kudos
9 Replies
JakeSkinner
Esri Esteemed Contributor

Hi Benji,

When adding the URL to a web browser, I believe it is using a 'GET' rather than a 'POST'.  You will need to use a POST to generate the token. 

You could achieve this using python:

import urllib, urllib2, json, ssl

username = "portaladmin"
password = "gis12345"

tokenURL = 'https://portal.domain.com/portal/sharing/rest/generateToken/'
params = {'f': 'pjson', 'username': username, 'password': password, 'referer': 'https://portal.domain.com'}
req = urllib2.Request(tokenURL, urllib.urlencode(params))
try:
    response = urllib2.urlopen(req)
except:
    gcontext = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
    response = urllib2.urlopen(req, context=gcontext)
data = json.load(response)
token = data['token']
print(token)
RebeccaStrauch__GISP
MVP Esteemed Contributor

Jake Skinner   I'm trying your code out, but getting an error on the   ssl.SSLContext line12

Traceback (most recent call last):
Python Shell, prompt 32, line 12
AttributeError: 'module' object has no attribute 'SSLContext'

I tried it in WingPro and in ArcGIS Desktop 10.3.1....maybe a Python version issue?  I'm using a modified version you posted a while back for working with my ArcGIS Server, but it did not have ssl in the code that I can see.  

Any suggestions?

0 Kudos
JakeSkinner
Esri Esteemed Contributor

Hi rastrauch‌, would you be able to provide the code you tried?

0 Kudos
RebeccaStrauch__GISP
MVP Esteemed Contributor

Hi Jake Skinner ,

I worked with it again, and I did get it working. (with your code above)

I think the error above was either my system just needed a reboot, or may have been the fact that our portal might not have been completely setup correctly.  We had to reauthorize and re-set our web adaptor yesterday as we are finally getting 10.5.1 tested. 

However, when I tried this morning, I was getting a different error.... (ValueError: No JSON object could be decoded) but that was because I was using the URL without the full domain name.  (for both the tokenURL and params referer).  Once I put the  <portal>.<domain>.local in, it worked.

I tested in both Wing Pro and ArcCatalog 10.5.1 and it is returning a token for me now.  Thanks

0 Kudos
ManviLather
New Contributor II

Thank you for sharing the script. I tested this in two environments. The script worked fine in env where SSL was set to False and gave the following error message for env with SSL = true: 

Runtime error
Traceback (most recent call last):
File "<string>", line 12, in <module>
AttributeError: 'module' object has no attribute 'SSLContext'

--Are we suppose to make any change in the script for env with SSL-True.?

0 Kudos
JakeSkinner
Esri Esteemed Contributor

Try the following script that uses the requests module instead.  The server variable is the name of the server where portal is installed (not the web adaptor):

import requests, json

# Disable warnings
requests.packages.urllib3.disable_warnings()

username = "gis\jskinner"
password = "*******"
server = "portal.esri.com

tokenURL = 'https://{0}:7443/arcgis/sharing/rest/generateToken/'.format(server)
params = {'f': 'pjson', 'username': username, 'password': password, 'referer': 'https://{0}'.format(server)}

r = requests.post(tokenURL, data = params, verify=False)
response = json.loads(r.content)
token = response['token']
print(token)
0 Kudos
maryandrews
New Contributor III

Jake Skinner

Thanks you for the alternative.  I'm converting a script I had working in 2.7.  With requests I'm able to generate a token but getting an error message when i try to query the service to see when a point was added.  

The error is :  TypeError: the JSON object must be str, bytes or bytearray, not 'dict'

Here is the bit of code giving me problems. Any thoughts?  Thank you!  

# Query service and check if created_date time 
params = {'f': 'pjson', 'where': "1=1", 'outfields': 'OBJECTID_1, AssetID, Status, Location, Notes ', 'returnGeometry': 'false', 'token' : token}
req = requests.post(tokenURL, data=params, verify=False)
response =json.loads(req.content)
data = json.loads(response)
for feat in data['features']:
Status = feat['attributes']['Status']
if Status == 6:
oidList.append(feat['attributes'][uniqueID])
AssetID.append(str(feat['attributes']['AssetID']))
Location.append(str(feat['attributes']['Location']))
Notes.append(str(feat['attributes']['Notes']))
0 Kudos
JakeSkinner
Esri Esteemed Contributor

mary andrews‌ it looks like the data variable is set to the response of the tokenURL requests.  You will need another request to the feature service URL.  Take a look at the following document on sending an e-mail when a feature is added.  It should give you an idea on how to generate a token, and then query a service.

by Anonymous User
Not applicable

Hi Jake,
I'm seeing the exact same error when requesting token from WAB. I've inherited the code from previous developer and I'm seeing this token url being generated in the code in ConfigLoader and tokenUtils files in jimu folder.
The URL is https://maps.ecosphere.fws.gov/portal/sharing/generateToken?f=json&username=abc&password=xyz&client=...https://myserver/mywebapp&expiration=60&callback=dojo_request_script_callbacks.dojo_request_script0

Any idea how callback is being appended to the url? Also wondering how to use POST method to generate token in WAB. Any help is greatly appreciated. 

0 Kudos