How should apps handle multiple credentials
See original GitHub issueUnlike IdentityManager, rest-js does not provide a means to handle multiple credentials, for example if:
- an app needs to connect to multiple servers using different credentials
- an app needs to connect to a server that is not federated w/ the current session’s portal
Up until now, I think our idea is that it is up to the app to manage multiple instance of IAuthenticationManager. For example to initialize multiple UserSessions and pass in a different authentication
depending on the url
.
However, I think there’s an opportunity for us to handle this at the library level better than how consuming apps can. For example, we could create a new type of IAuthenticationManager
called IdentityStore
or AuthenticationStore
that could return the appropriate token based on the url
passed to getToken()
. Analogous to IdentityManage’s registerToken() it would have a method to register credentials (IUserSessionOptions) for all requests that start with a given server’s URL like identityStore.add(sever: string, session: IUserSessionOptions): void
. Example:
// create a single store that we'll pass to all requests
const identityStore = new IdentityStore();
// add credentials for working w/ our server
const ourServer = 'https://gissvr.ourorg.gov/arcgis/rest/services';
identityStore.add({
server: ourServer,
session: {
// these would come from a dialog
username: 'us',
password: 'secret'
}
});
// add credentials for working w/ their server
const theirServer = 'https://mapsvr.theirorg.com/arcgis/rest/services';
identityStore.add({
server: theirServer,
session: {
// these would come from a dialog
username: 'them',
password: 'alsoSecret'
}
});
// query our feature sever
const ourFeatureServerUrl = `{ourServer}/rivers/0`;
queryFeatures({
url: ourFeatureServerUrl,
// when identityStore.getToken() is called, it will return the token for our server
authentication: identityStore
});
// query their feature sever
const theirFeatureServerUrl = `{theirServer}/streets/0`;
queryFeatures({
url: theirFeatureServerUrl,
// when identityStore.getToken() is called, it will return the token for their server
authentication: identityStore
});
I think the easiest initial implementation would be for add()
to create a new UserSession
under the hood, and the store would in turn call that session’s getToken()
for each request to the associated server. We might be able to refactor so that the store doesn’t need to manage multiple instances of IAuthenticationManager
.
I think this also provides the foundation that app authors would need to emulate IdentiyManager’s behavior to automatically show a dialog when it tries to make a request to a protected resource for which it doesn’t have credentials. The app can catch authentication errors, show a dialog (using it’s UI framework of choice) and after successfully authenticating with the server, add the server and valid credentials to the store.
cc @qlqllu
Issue Analytics
- State:
- Created 5 years ago
- Comments:5 (5 by maintainers)
Top GitHub Comments
This sounds like a great solution @tomwayson
I would suggest that we also support a scenario where the consuming app has the token (from a cookie, localstorage, some other auth flow managed by the app), but not the username/password? As long as we can do that in addition to passing in the un/pwd, that would be good with me.
For the
server
should we pass just thehostname
? or protocol + hostname + port etc? Would we ever need different creds for http vs https? or port 80 vs 7772?@tomwayson FWIW this is exactly why I designed IAuthenticationManager manager the way I did. I just really didn’t want to take the extra complexity leap into a full blown
IdentityManager
implementation.