ESRI JS API: IdentityManager: Store the oauth state in local-storage ?

1504
8
03-04-2020 03:48 PM
MichalGasparovic1
New Contributor III

Hi, I've asked a similar question before, and also resolved it myself here:
ESRI JS API: IdentityManager: how to use localStorage 

This was for the scenario, where I've used the popup: true for the OAuth2.0 authentication.

However, I'm now in the scenario where I have to use redirect to the agol's/portal's oAuth page insteas of a popup, so I have to use the popup: false.

This seem to work fine, but the problem is that user has to approve the access each time he opens the app, because the oath state is stored in session-storage in esriJSAPIOauth property, instead of local-storage. I guess this all happens as there is no presence of any 'Keep Me Signed In' or similar checkbox for the enterprise login oAuth page.

Does anyone know how can I force the IdentityManager to store the redirected oauth state into the session-storage ?

Thank you.

ESRI JS API: 4.14
AGOL/PORTAL SECURITY: Enterprise logins

0 Kudos
8 Replies
MichalGasparovic1
New Contributor III

So as I've learned from the ESRI support this is not possible to do the enterprise logins. So time for hacking again....

If anyone is interested, I've ended up copying the session storage entry that IdentityManager genarates into the local storage after each login. This handles also agol/any portal.

It's not the neatest piece of code but serves the purpose.

changeOAuthStorage() {
  // REMOVE ANY ESRIJSAPIOAUTH entries in the session or local storages
  const key = 'esriJSAPIOAuth';
  if (window && window.sessionStorage) {
    const oauth = window.sessionStorage.getItem(key);
    if (!oauth) {
      return;
    }
    const oauthObj = JSON.parse(oauth);
    if (window.localStorage) {
      const localStorageoAuths =  window.localStorage.getItem(key);
      if (!localStorageoAuths) {
        window.localStorage.setItem(key, JSON.stringify(oauthObj));
        window.sessionStorage.removeItem(key);
        return;
      }
      const lsAuth = JSON.parse(localStorageoAuths);
      lsAuth['/'] = {...lsAuth['/'], ...oauthObj['/']};
      window.localStorage.setItem(key, JSON.stringify(lsAuth));
      window.sessionStorage.removeItem(key);
    }
  }
}

I've also noticed that IdentityManager 3.x has different inner workings to 4.x as it's not storing any serialized state into session nor the local storage. Has the capability of restoring the state even if accessing the internal portal externally via azure application proxy. 4.x cannot handle it.

Ranga_Tolapi
Occasional Contributor II

Wow..! Very impressive..! :clapping_hands:

0 Kudos
RichardK
New Contributor

I only have one word for this. Awesome.

0 Kudos
HarshvardhanSwami-Provista
New Contributor

Hi @MichalGasparovic1 ,

Greetings!

I hope you are doing well. I must have to say this solution is great and, I have a question, can we implement this for ArcGIS Online (if yes, then where can we put this code). I am asking this because I am implementing this with ArcGIS web app builder custom application and AGOL in the backend.

Any assistance you can provide would be greatly appreciated.

Thank you,

Harsh

0 Kudos
MichalGasparovic1
New Contributor III

Hi Harsh, well that I don't know. never worked with the webapp builder so not sure to what extent you can control the oauth process, tbh I don't think it's possible as the core of the application that runs your web application builder code handles all the oauth communication. Sorry

0 Kudos
luckachi
Occasional Contributor

Michal, I am looking to implement this in a pure ArcGIS JS page but I am unsure where this is supposed to go. I receive an error message that reads 

Uncaught SyntaxError: Unexpected token '{'

Should this be part of a function?

What I am trying to do is, I have a link in the feature popup within my web app that opens up an external page that shows just the desired feature and the attributes, what I'd like is for the log in information to persist to that page so users do not have to log in again or click allow for "Request for Permission" everytime they click on a link.

0 Kudos
MichalGasparovic1
New Contributor III
Hi, that's bit unusual to login and query for data on one page, and then
from popup open new page where you query rest service again.

If you already have the token, just pass it in the queryparams to a new
page and use it for your queries on the new page..

You are not providing enough details about the error, but perhaps you are
not formatting the response as JSON or the JSON has an invalid structure?
Hard to say
0 Kudos
luckachi
Occasional Contributor

Sorry I was not very clear. I have a web mapping application (not JS, AGO)  that is not public due to the nature of the information collected. The link within the popup opens a page that sits within our website structure that only displays the selected feature (the feature in which you viewed the popup for and clicked the link) and the attributes. This is so users can print it for annual reporting. 

That must be, I was not aware this involved JSON. Right now I just have this, which worked to get rid of the full log in and just requires you to click Allow but I would like this page to know whether or not the user is already logged in to AGO and not ask anything prior to the page loading.

var appURL = "our URL",
  appURLSharing = appURL + "/sharing";


let info = new OAuthInfo({
   appId: "our app ID",
   popup: false,
   preserveUrlHash: true
 });

esriId.registerOAuthInfos([info]);

 

0 Kudos