Help me understand tokens

729
4
Jump to solution
10-19-2018 11:01 AM
MollyFoley
Regular Contributor

I'm messing around with securing my services and plan on putting in place token-based authentication for our JS API application. I'm just trying to get a handle on what tokens do and how they work. I have made a user in our ArcGIS server, assigned it the "User" role, and have set one service to only allow access by logged in users that are part of the "user" role. I went to generate a token at https://domain.com/serverName/tokens and filled that out to generate the token. I filled out the HTTP referer field as www.domain.com with the domain our JS API web app sits on. 

Now, when I try to access that service via the rest endpoint with the token, I get taken to a login page. Isn't the token supposed to automatically log me in and give me access to the service? If not, how is the token doing anything different than just going to services page and hitting "Login"?

This is how I'm trying to access the service with the generated token:

https://www.domain.com/serverName/rest/services/myfolder/myservice/GPServer?<token here>

Am I misunderstanding what tokens do?

0 Kudos
1 Solution

Accepted Solutions
MollyFoley
Regular Contributor

The final URL should look like this...what I was missing was defining the task after you define what type of server you're trying to access:

https://www.domain.com/serverName/myfolder/myservice/typeOfServer/task?<token>

For example:

https://www.blahblahblah.org/natureServer/HabitatManagement/HabitatManagement/GPServer/HabitatManage...

**Note that I am using the above URLs with a web adapter installed so I can access my services directly from my domain. If you're not using a web adapter then it'd be something more like this:

https://natureServer:6080/arcgis/HabitatManagement/HabitatManagement/GPServer/HabitatManagement?a89sd79faklj234fa087sljk34dadf878234klsd897234lksdoeroi

To illustrate this further, from your main rest services page, your folders:

If I click on HabitatManagement, I get taken to my services:

If I click on that service, I get taken to my tasks

Those make up the three parts of your URL. After you append the token to end of that (don't forget the question mark!) then it should log you in automatically and give you access.

View solution in original post

4 Replies
JonathanQuinn
Esri Frequent Contributor

The first thing that comes to mind, (and only because you didn't explicitly mention it), is that you're not sending the same value of the referer header as the one you use to generate the token. They have to match exactly.

0 Kudos
MollyFoley
Regular Contributor

So you're saying in the HTTP referrer field, I should be using https://www.domain.com/serverName/  ? Or would it be https://www.domain.com/serverName/myfolder/myservice/GPServer ? The domain our web app sits on and the token URL are the same domain, if that matters.

0 Kudos
MollyFoley
Regular Contributor

The final URL should look like this...what I was missing was defining the task after you define what type of server you're trying to access:

https://www.domain.com/serverName/myfolder/myservice/typeOfServer/task?<token>

For example:

https://www.blahblahblah.org/natureServer/HabitatManagement/HabitatManagement/GPServer/HabitatManage...

**Note that I am using the above URLs with a web adapter installed so I can access my services directly from my domain. If you're not using a web adapter then it'd be something more like this:

https://natureServer:6080/arcgis/HabitatManagement/HabitatManagement/GPServer/HabitatManagement?a89sd79faklj234fa087sljk34dadf878234klsd897234lksdoeroi

To illustrate this further, from your main rest services page, your folders:

If I click on HabitatManagement, I get taken to my services:

If I click on that service, I get taken to my tasks

Those make up the three parts of your URL. After you append the token to end of that (don't forget the question mark!) then it should log you in automatically and give you access.

JonathanQuinn
Esri Frequent Contributor

I'm glad that it's working, but I'm surprised it was a problem with the URL and not with the referer. For example:

import urllib, urllib2, json, traceback, ssltoken
URL = 'https://sampleserver6.arcgisonline.com/arcgis/tokens/generateToken'
tokenParams = dict(username='user1',password='user1',client='referer',expiration='1440',referer="https://server.domain.com",f="json")
tokenRequest = urllib.urlopen(tokenURL,urllib.urlencode(tokenParams))
jsonResponse = json.loads(tokenRequest.read())
token = jsonResponse['token']‍‍‍‍‍‍‍‍

I create a referer based token. If I make a request without providing any headers, I get invalid token:

restParams = dict(f="json",token=token)
restRequest = urllib.urlopen("https://sampleserver6.arcgisonline.com/arcgis/rest/services",urllib.urlencode(restParams))
print(restRequest.read())

{"error":{"code":498,"message":"Invalid Token","details":[]}}

If I use a different referer, I get the same response:

request = urllib2.Request("https://sampleserver6.arcgisonline.com/arcgis/rest/services")
request.add_header('referer',"https://server")
restRequest = urllib2.urlopen(request,urllib.urlencode(restParams))
print(restRequest.read())

{"error":{"code":498,"message":"Invalid Token","details":[]}}

However, if I use the correct referer, then it works:

request = urllib2.Request("https://sampleserver6.arcgisonline.com/arcgis/rest/services")
request.add_header('referer',"https://server.domain.com")
restRequest = urllib2.urlopen(request,urllib.urlencode(restParams))
print(restRequest.read())

{"currentVersion":10.6,"folders":["AGP","Elevation","Energy","LocalGovernment","Locators","NetworkAnalysis","Oblique","OsoLandslide","ScientificData","StoryMaps","Sync","Utilities"],"services":[{"name":"911CallsHotspot","type":"GPServer"},{"name":"911CallsHotspot","type":"MapServer"},{"name":"Census","type":"MapServer"},{"name":"CharlotteLAS","type":"ImageServer"},{"name":"CommercialDamageAssessment"....}

If the valid referer was sent along with the request to an invalid page, you shouldn't get an invalid token response.

0 Kudos