Esri / ago-assistant

A swiss army knife for your ArcGIS Online and Portal for ArcGIS accounts
https://ago-assistant.esri.com/
Apache License 2.0
152 stars 89 forks source link

Support SAML logins for Portal for ArcGIS #115

Closed slibby closed 7 years ago

slibby commented 8 years ago

Right now, Enterprise logins are supported for AGO because AGO-assistant leverages the oauth dialog. For Portal, you can only use built-in accounts or IWA. Ideally, you could switch to a model where oauth is used for both, or where ago-assistant would allow you to log in to a SAML-authenticated Portal.

ecaldwell commented 8 years ago

Do you have a good feel for how this could be implemented? What is the login experience in a Portal with SAML based authentication?

slibby commented 8 years ago

I don't know how from a Javascript/HTML perspective, but here's a Portal with SAML configured so you can see the UI: https://maps.test.rcview.redcross.org/portal/home/

Right now for that portal, I can only login with a built-in account, not a SAML account.

slibby commented 8 years ago

@ecaldwell I think it would require registering ago-assistant as an oauth application with your Portal, then having a UI in AGO-assistant to use oauth OR the simple generatetoken method it's using now. the AGO login uses oauth, would it be possible to reuse that easily?

I really should start learning javascript I guess.

ecaldwell commented 8 years ago

OK, in that case you should just be able to put the new registered app info in this section. Since it requires modifying the source code, this also means you would have to rehost the app on your own web server.

nheminger commented 8 years ago

Would this be fixed by programmatically using a different url in the oauth info object based on user input? Can the appid be negotiated or retrieved based on the portal url?

ecaldwell commented 8 years ago

@nheminger Interesting thought. There's not a good way to search in Portal for a specific registered URL...it would have to search all type: Web Application then inspect each until it found one with the url to the hosted app (i.e. https://ago-assistant.esri.com). Then it could grab and replace the appId and portalUrl in the OAuth object.

Maybe a simple approach would be to allow for a URL querystring parameter in the app. If somebody loads the app with https://ago-assistant.esri.com?portalUrl=<myPortal.domain> then it could trigger the above logic. If it doesn't see that URL parameter, it could just use the default for ArcGIS Online. Think that would work?

slibby commented 8 years ago

Love that idea, @ecaldwell. could also specify portalurl and appid in the url and use that to populate the rest.

ecaldwell commented 8 years ago

@slibby I like that better. Less logic needed in the app.

jgravois commented 8 years ago

i just tried testing a SAML enabled Portal and am seeing some funny behavior. with the configuration below the OAuth popup appends two /sharing/ directories in its request to the SAML enabled Portal.


// *** ArcGIS OAuth ***
var appInfo = new arcgisOAuthInfo({
  appId: "Cyn33oUlgf0qLhEf",
  popup: true,
  portalUrl: "https://samlpadfs.ags.esri.com/arcgis/sharing"
});

https://samlpadfs.ags.esri.com/arcgis/sharing/sharing/oauth2/authorize?client_id=Cyn33oUlgf0qLhEf&response_type=token&state=%7B%22portalUrl%22%3A%22https%3A%2F%2Fsamlpadfs.ags.esri.com%2Farcgis%2Fsharing%22%7D&expiration=20160&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fbuild%2Foauth-callback.html

if i remove sharing, i encounter an error in the code before a request is even triggered.

  portalUrl: "https://samlpadfs.ags.esri.com/arcgis"
// ...
// line: 1875
esriId.getCredential(appInfo.portalUrl, {
  oAuthPopupConfirmation: false
})

dojo.js:94 Error: Unknown resource - could not find token service endpoint.(…) "Error: Unknown resource - could not find token service endpoint.

ecaldwell commented 8 years ago

I think this is related to how esriId interprets the appInfo object. My understanding is that it automatically adds /sharing when the url is arcgis.com, but you need to do it manually for Portal.

Try changing this line to esriId.checkSignInStatus(appInfo.portalUrl + '/sharing') and see if it gets any further.

jgravois commented 8 years ago

@ecaldwell. your suggestion, plus manually tacking /arcgis/ back onto the 'portalUrl' referenced in the Portal instantiation in the callback allowed me to sign in and see content.

// my config object from line 28 of main.js
var appInfo = new arcgisOAuthInfo({
   appId: "Cyn33oUlgf0qLhEf",
   popup: true,
   portalUrl: "https://samlpadfs.ags.esri.com/arcgis"
});

/*
the above necessitates that you have created a portal item to register your new application and configured redirect_uris for it to ensure that its considered safe to forward folks back to your app
mine:
http://localhost:8080/index.html, 
http://localhost:8080/oauth-callback.html
*/ 

// further down in main.js...

// line 105: hardcoded reference to add '/arcgis/' if necessary
if (app.portals.sourcePortal.portalUrl.indexOf("/arcgis/") <= -1) {
  // if ‘/arcgis/‘ isn’t already present in the url, append it
  app.portals.sourcePortal.portalUrl += "/portal/";
}
app.portals.sourcePortal.self().done(function(data) {

// line 1698: hardcoded reference to add '/sharing/' to url 
esriId.checkSignInStatus(appInfo.portalUrl + '/sharing/')
  .then(
    function(user) {
    // ..
    app.portals.sourcePortal = new portalSelf.Portal({
        // line 1704: hardcoded reference to add '/arcgis/' to url.
        portalUrl: user.server + "/arcgis/",
        username: user.userId,
        token: user.token
    });

for anyone following along at home, this extra configuration is currently necessary to get ago-assistant to use OAuth to authenticate users to a custom Portal when clicking the big green 'Login' button because the existing option in the production app for signing into a Portal (whether SAML enabled or not) falls back to making a direct request to fetch a token instead of using OAuth.

:smile:

phoeffler84 commented 8 years ago

Working on this end - thanks @jgravois @ecaldwell and @slibby !

jgravois commented 8 years ago

thanks for confirming @phoefflernps! i'm going to try and give @ecaldwell a hand with refactoring the build process. i'll also be thinking about how to organize a PR so that the production app can support OAuth Portal access without all these hardcoded tweaks.

jgravois commented 8 years ago

i finally got ahold of a SAML portal for testing and after pulling down the latest updates and after updating only the config.json, signing in w/ OAuth, i'm not able to login and work with content until _after_ i refresh the page.

// redirect uri is http://localhost:8080
"appId": "0Gbekqt3u9ZLcaXb",
"portalUrl": "https://samlpadfs.ags.esri.com/arcgis"
/*
generic SAML publisher credentials for the portal can be found internally in 
http://mediawikidev.esri.com/index.php/10.5_Portal_QA
/*

in the initial login sequence, a request that omits /arcgis/ is made to https://samlpadfs.ags.esri.com/sharing/rest/portals/self?

i noticed an inverse problem when working with NPS (hence my suggestion to update checkSignInStatus), but now, even when calling grunt dev, the code in main.js is too obfuscated to debug happily.

phoeffler84 commented 7 years ago

We have two hard-coded local instances of this that date back to September. We'll need to update to a more recent version assuming that we can implement the changes made with help from @jgravois. Right now we're facing a significant challenge of moving content from our old Portal (built-in user accounts) to a new Portal (SAML-based accounts) - to use the Assistant for that purpose the sign on dialog under the copy function needs to support the SAML-based sign on. Thoughts on if that's possible using similar techniques as before? We have a great demand for this and not many alternatives. If this is a separate issue I can open it as such. Thanks!

jgravois commented 7 years ago

@phoefflernps are you hoping to upgrade to v2.7.2?

i'd have to blow out some cobwebs, but i should be able to set aside some time in the next couple days to re-digest the notes above and see whether the same changes are necessary to get SAML working in the most recent release.

phoeffler84 commented 7 years ago

@jgravois, the newer version would be ideal if we can continue to support SAML-based sign on. Our more pressing need is to allow users to copy content from a Portal that has only built-in accounts (would not require SAML-based auth for first Portal sign on) to the Portal that is using SAML-based authentication, which means supporting this (hard-coded or otherwise) at the I want to... Copy Content, Another Account dialog box. We hope to be able to upgrade to the newest version and support the SAML-based authentication in both areas, using as many copies of Assistant as necessary. Thanks for thoughts on the above!

jgravois commented 7 years ago

since the latest release has two different sign in dialogs (one for ArcGIS Online and one for Portal) i think that if we configure the ArcGIS Online sign in to point at your own SAML enabled Portal and leave the Portal sign in alone you'll be able to use the context dialog you mentioned to copy items between the two.

does that sound right to you?

phoeffler84 commented 7 years ago

Good point - that may cover both of our cases, as long as it works as expected and we can change some labels on the front end. May be a straightforward fix after all, I'll attempt this and report back. I expect the next request will be to copy between Portal and ArcGIS Online (both SAML-enabled), but we can deal with that down the road. Thanks!

jgravois commented 7 years ago

May be a straightforward fix after all.

it should be, but give a shout if you get stuck.

we can deal with that down the road.

@slibby was right back in early 2016. it would still be great to get this app using OAuth exclusively.

jgravois commented 7 years ago

i sanity checked this today and the workflow i outlined above (in https://github.com/Esri/ago-assistant/issues/115#issuecomment-249270264) works just as well in version 2.7.2 as it did back then.

the important thing to remember is that the maintainers of this project make downloads of both the raw source for the entire project and the prebuilt website code thats actually ready for deployment each time they tag a release.

this means you have two different options to point ago-assistant v2.7.2 at your own SAML enabled portal instead of ArcGIS Online.

update the built project

  1. download ago-assistant-2.7.2.zip from the v2.7.2 release page.
  2. unzip the folder and open main.min.js
  3. update the appId and portalUrl at the very top of the file.

update the raw source

  1. download Source code (zip) from the v2.7.2 release page.
  2. unzip the folder and cd into it using cmd or terminal
  3. npm install the project dependencies
  4. open config.json and update the appId and portalUrl
  5. run npm run build to concatenate and minify the current contents of /src in a new adjacent /build directory.
  6. use a web server to host the contents of the /build/ folder (not the /src/ folder)
rwmajor2 commented 7 years ago

Addressed by PR #194.

jgravois commented 7 years ago

🎉 :tada::tada: