-
Notifications
You must be signed in to change notification settings - Fork 119
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement UserCredentials
and ApplicationCredentials
#10
Comments
@patrickarlt Heroic work decoding what the IdentityManager is doing! I totally agree that requesting separate tokens from "well-known-servers" is silly and wasteful. As you note, there are myriad other vectors, likely easier, to compromise a user's token. One question - since I'd assume the implementation of Also - I created #11 regarding building a set of demo apps to validate that this library will work for our various use-cases. |
@dbouwman Rereading my comment it was unclear that BOTH |
@patrickarlt Perfecto! |
Basic implementation of |
Based on discussion in https://github.com/ArcGIS/arcgis-rest-js/issues/5 we are going to implement authentication as follows:
Since the request method and the
UserSession
/AuthSession
objects will be closely coupled now I think this should all go intoarcgis-rest-core
.At a glance this means adding:
ArcGISAuthError
.ErrorTypes
which will exposeArcGISAuthError
andArcGISRequestError
checkForErrors
will have to throwArcGISAuthError
orArcGISRequestError
depending on what went wrong.Now for some of the more challenging things:
Retrying authentication requests
The more I think about it the more I feel that we shouldn't try to implement automatic request retrying for a few reasons:
Session
have to be event emitters which means more dependencies.I wouldn't be opposed to "simple retrying" like so:
This makes retrying requests when auth fails relatively simple and it makes sense in terms of the promise-based implementation we have today. If we want to implement retries this is the way I would handle it.
"Federation"
In the JS API the identity manager does "Federation" between servers and portals. It works like this:
esri.request
is called.IdentityManager
looks up to see if the server being called is on the list of CORS enabled servers it knows about.a. If the server is on the list of CORS enabled servers the request is sent.
IdentityManager
saves this in its internal cache of "server infos".b. If the request is not on the list of CORS enabled servers a request is first sent to a request is sent to
${SERVER}/arcgis/rest/info?f=json
if the request responds we know the server supports CORS then the request is sent.IdentityManager
saves this in its internal cache of "server infos".IdentityManager
for the token for the server the service sits on.a. If we know the server info (see 2-b or 3-2-b) then proceed to step 4
b. If we do not know the servers server info look it up (step 2-b).
IdentityManager
saves this in its internal cache of "server infos" and we can proceed to step 4owningSystemUrl
. if the system has noowningSystemUrl
then the user authenticates directly with the server but I'm not entirely sure how that works.a. we have a token for the
owningSystemUrl
cached inIdentityManager
so make a request to${owningSystemUrl}/sharing/generateToken
and ask it to generate a token for the server our service is sitting on. This token is cached inIdentityManager
. Goto step 5b. We do not have a token for the
owningSystemUrl
, popup the identity manager and ask the user to authenticate into theowningSystemUrl
. Once the user signs their token is cached inIdentityManager
. repeat step 4-a.In practice here is how this works for the following:
traffic.arcgis.com
is not in the list of CORS enabled servers we need to make a request to https://traffic.arcgis.com/arcgis/rest/info?f=json.Here is how the same request works with a token registered.
Replace token with a token from a user or app.
traffic.arcgis.com
is not in the list of CORS enabled servers we need to make a request to https://traffic.arcgis.com/arcgis/rest/info?f=json.In short this is really complicated but does accomplish a few goals.
This entire infrastructure is setup most to support the security use case. Doing the full generate token dance, especially with known services like traffic.arcgis.com seems silly. If someone has man-in-the-middled you and broken HTTPS (somehow) they can see your portal key anyway when it gets sent to
/sharing/generateToken
. If you send your portal token to a malicious service you 1 open up something with a malicious resource in it, 2 make a request to that resource, 3 sign in. It would probably be easier to just spoof the JS API experience and steal portal tokens in a simple phishing attack.I would propose the following:
trustedServers
which defaults to any server under the arcgis.com. Developers can add additional servers.request
is to atrustedServer
in thatsession
attach the token and make the request. This works because tokens from theowningSytemUrl
are also valid on any federated servers.request
is not to atrustedServer
do the following:server/info
to get theowningSystemUrl
.token
for theowningSystemUrl
owningSystemUrl/generateToken
to get a token for that server. Save this token and server info so we can look it up again later.request
with our new token.This minimizes extra requests as much as possible. Standard AGOL users should see no additional requests. Users on Enterprise should see an extra
server/info
andowningSystemUrl/generateToken
once per ArcGIS Server they call.Final Design
The text was updated successfully, but these errors were encountered: