Hi everyone,
I am trying to integrate the OAuth functionality in a simple app developed with the Web AppBuilder embedded with Portal and then deployed.
I have obtained the AppID and I have looked into the OAuth 2 basic sample, but I don't understand how to integrate it in my app.
I suppose that I have to modify the index.html, but I don't know how.
Can anyone point me in the right direction?
Thanks,
Marco
I have one example making app login with AGOL and this proxy-oauth. I just change the proxy.ashx and the Index.html for the application to request the TOKEn before load the application (inside the <script> tag for index.html).
Add the variables to web.config for the proxy configuration with username, password, clientid and clientsecret and make this changes like descrived:
<add key="user" value="loginname"/>
<add key="pass" value="password"/>
<add key="clientid" value="1111111111"/>
<add key="clientsecret" value="2222222222222222222"/>
Change the function ProcessNormalRequest (inside proxy.ashx) to add one validation just like below (before make the URL request ~line 232):
if (uri.Contains("oauth2/token"))
{
// Get the AppSettings section.
NameValueCollection appSettings = ConfigurationManager.AppSettings;
string appSecret = "";
string user = "";
string pass = "";
string clientid = "";
string clientsecret = "";
for (int i = 0; i < appSettings.Count; i++)
{
System.Diagnostics.Debug.WriteLine(appSettings.GetKey(i) + "," + appSettings);
//if (appID == appSettings.GetKey(i))
//{
// appSecret = appSettings;
//break;
//}
if ("user" == appSettings.GetKey(i))
{
user = appSettings;
}
if ("pass" == appSettings.GetKey(i))
{
pass = appSettings;
}
if ("clientid" == appSettings.GetKey(i))
{
clientid = appSettings;
}
if ("clientsecret" == appSettings.GetKey(i))
{
clientsecret = appSettings;
}
}
uri += "&username="+ user + "&password="+ pass + "&client_id=" + clientid + "&client_secret=" + clientsecret + "&grant_type=client_credentials";
}
and in the index.html of the main application, insert one script just like below:
<script>
/*******************************
* This is the function you can modify to customize the loading page
* This function will be invoked when one resource is loaded.
********************************/
// var progress;
// function loadingCallback(url, i, count) {
// var loading = document.getElementById('main-loading-bar');
// loading.setAttribute('title', url);
// if(!progress){
// progress = document.createElement('div');
// progress.setAttribute('class', 'loading-progress');
// loading.appendChild(progress);
// }
// progress.style.width = (((i - 1)/count) * 100) + '%';
// }
var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://yourserver/proxyoauth/proxy.ashx?https://www.arcgis.com/sharing/rest/oauth2/token?expiration...', true);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.onreadystatechange = function () {
// do something to response
console.log(this.responseText);
testeTopken = this.responseText;
//expiraUTCformat = Date.now() + (testeTopken.substr(testeTopken.indexOf(',"expires_in":')+14, 5)*1000);
expiraUTCformat = Date.now() + 86400000);
testeEsriJSAPI1 = testeTopken.replace('{"access_token":','{"/":{"https://yourportalserver":{"expires":'+expiraUTCformat+',"ssl":true,"token":');
testeEsriJSAPI1 = testeEsriJSAPI1.substr(0, testeEsriJSAPI1.indexOf(',"expires_in":'));
testeEsriJSAPI1 = testeEsriJSAPI1 + ',"userId":"username"}}}';
localStorage.setItem('esriJSAPIOAuth', testeEsriJSAPI1);
};
xhr.send();
</script>
Hope this help you.
Nothing to do: it keeps redirecting me to the same page. Probably I am missing something somewhere...
But thank you anyway, Rafael: you have been really kind!
I have a widget using OAuth2 functionality. In the widget's postcreate function, I call this function
_logon() {
var theAppId, thePopupCallbackUrl;
var location = this._appInfo.find(x => x.location === window.location.hostname);
if (location !== undefined) {
theAppId = location.appID;
thePopupCallbackUrl = location.popupCallbackUrl;
} else {
new Message({
titleLabel: 'Error',
message: 'This site will not allow ArcGIS.com login'
});
this._logoff();
return;
}
var info = new ArcGISOAuthInfo({
appId: theAppId,
popupCallbackUrl: thePopupCallbackUrl,
popup: true,
portalUrl: this.config.agol.portalUrl
});
esriId.registerOAuthInfos([info]);
esriId.getCredential(info.portalUrl, {
oAuthPopupConfirmation: true
}).then(lang.hitch(this, function () {
new arcgisPortal.Portal(this.config.agol.portalUrl).signIn().then(lang.hitch(this, function (portalUser) {
var portal = portalUser.portal;
var queryParams = {
num: 100,
q: 'owner: ' + this._ownerName + ' AND type: Feature Service'
};
portal.queryItems(queryParams).then(lang.hitch(this, function (result) {
if (result.total > 0) {
if (array.some(result.results, lang.hitch(this, function (item) {
this._SPGridUrl = item.url;
return this._SPGridUrl.indexOf(this._baseGridLayerName) > -1; //
}))) {
this._prepareEditor();
} else {
this._SPGridUrl = null;
new Message({
titleLabel: 'Logging out',
message: 'The grid was not found in your account!'
});
}
} else {
this._SPGridUrl = null;
new Message({
titleLabel: 'Logging out',
message: 'The grid is not available to edit!'
});
}
}));
}
)).otherwise(
function (error) {
new Message({
titleLabel: 'Error occurred while signing in',
message: error
});
}
);
}))
.otherwise(lang.hitch(this, this._promiseRejected));
},
When the user starts the widget, after they successfully log in, the code searches for a feature layer (which begins with the string indicated in the variable this._baseGridLayerName) in their AGOL contents and added to their map (in the _prepareEditor function). The variable this._appInfo contains the AppID and the popup callback URL. In my case, I have several of these defined, since I have versions running on my laptop, a development server, and the production server.
this._appInfo = [
{
"location": "productionURL",
"appID": "xxxxxxxxxxxxxxxxx",
"popupCallbackUrl": "productionURL/oauth-callback.html"
},
{
"location": "developmentURL",
"appID": "xxxxxxxxxxxxxxxxx",
"popupCallbackUrl": "developmentURL/oauth-callback.html"
},
{
"location": "laptopURL",
"appID": "xxxxxxxxxxxxxxxxx",
"popupCallbackUrl": "./oauth-callback.html"
}
]
Thank you very much, Ken. I will look into your code and let you know if I can manage to replicate it.
I would have preferred a solution without the use of a widget, but I suppose that it will work just fine.
Sit Sit,
Please let me know if you were able to figure this out. I also have a WAB App that accesses secure services and I would like to use the OAuth Named User Login Popup instead of the AGOL Username and Password.
Thanks,
Scott