Secured service with token and dynamic insert in map

5222
11
05-27-2010 10:58 PM
GiosiaPoma
New Contributor III
Hi everybody,
I'm trying, in a simple example, to add a secured service with token in a map.

At the moment I don't use https protocol. All is on http.

That's my workflow of the mxml file, all this steps are made in actionscript:

1. When the application is creationComplete I make a request to the token service with user, pass, clientid and expiration time
2. When the token is generated, I have the correct string in my handler and with this token I create a new ArcGISDynamicMapServiceLayer with the url and token.
3. Add the new object to the map with addLayer

In code:
var token:String = RequestToken('user','password');
var layerProtected:ArcGISDynamicMapServiceLayer = new ArcGISDynamicMapServiceLayer("http://server/arcgis/rest/services/service1/MapServer", null, token);
mappa.addLayer(layerProtected);

--> result: no secured service on my map. Error token not valid
This is the response viewed with Firebug when I try to make the request to the protected service:
{"error":{"code":498,"message":"Invalid token","details":[]}}

But If I try to use the previous generated token in a simple mxml file with tags <esri:ArcGISDynamicMapServiceLayer and I insert the token in the attribute of the above tag the map is shown...
In code:
<esri:ArcGISDynamicMapServiceLayer url="http://server/arcgis/rest/services/service1/MapServer" token="CRnSk2v0ukFyP87T97Yh_10IQCLhj6uBBlSwwmVXPszYSxDMBM4FdejQzqPWDEJNuzuTyt1pteZHgO0jTxvIKXG_6J4Mq0QQJoU1KQWbpEw."/>

What's the issue? What's my mistake? Have you any suggestions?
Tags (2)
0 Kudos
11 Replies
RobertScheitlin__GISP
MVP Emeritus
Giosia,

   The likely issue is that your RequestToken function is not returning before your code attempts to use that token string. Try using the actual token string in you action script code and see if that works if you don't like that then listen for your RequestToken function to return before you add your ArcGISDynamicMapServiceLayer.
0 Kudos
GuillermoMarinez
New Contributor
you can not use the token string variable after the code line "var token:String = RequestToken('user','password');" becouse the request of  token is  asynchronous. you must use this variable in the result function of the listener event
0 Kudos
GiosiaPoma
New Contributor III
Thank for the response Robert and Guillermo,

I've made a mistake with the code copy/paste. The object with the protected map is created in the result handler of the RequestToken function and at this moment I have the token that I use in dynamic mode and with the esri tag but the error is always invalid token. Did it work in your application?

Thank for your replies...

regards
0 Kudos
RobertScheitlin__GISP
MVP Emeritus
Giosia,

    I have not had any issue using secure map services. I don't use the RequestToken function though because you then are putting your user name and password into the code, and that is not very secure.
0 Kudos
GiosiaPoma
New Contributor III
Hi Robert,
thank for your reply.
I don't insert user and password in the code. My goal is to have a login screen with a php service that make a call to ldaps repository. All is made over https protocol. With the possibility to use dynamically token service in the ags I don't need to store in the code the token but add the generated code automatically.
The problem is that doesn't work dynamically... and I don't understand why... Nobody have an idea??? Esri guru's?

Thank you

I post my test page... if any have an idea... it's apprecieated.

Now is all in http protocol but in the future all goes to https...

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:esri="http://www.esri.com/2008/ags"
pageTitle="Example - ArcGIS API for Flex connecting to a dynamic AGS service"
creationComplete="init()">

<mx:Script>
<![CDATA[
import mx.binding.utils.BindingUtils;
import mx.rpc.http.HTTPService;
import mx.controls.Alert;
import mx.rpc.events.ResultEvent;
import mx.rpc.events.FaultEvent;
import com.esri.ags.layers.ArcGISDynamicMapServiceLayer;

private var theToken:String;

private function init():void {

RequestToken('ldapUser','ldapPassword'); // this value will be replaced with data from acces form
}

public function RequestToken(username:String, password:String):void {
var http:HTTPService = new HTTPService();
http.addEventListener( ResultEvent.RESULT, tokenResultHandler );
http.addEventListener( FaultEvent.FAULT, faultHandler );

http.url = "http://*******:8399/arcgis/tokens?request=gettoken&username="+ username +"&password="+ password +"&clientid=ref.http://***.***.ti.ch&expiration=1440";

http.method = "GET";
http.resultFormat = "text";

http.send();

function faultHandler(event:FaultEvent):void
{
Alert.show(event.fault.toString());
}
function tokenResultHandler(event:ResultEvent):void
{
theToken = event.result.toString();
Alert.show(theToken);
// adding secured service
// this don't work ...
var mProt:ArcGISDynamicMapServiceLayer = new ArcGISDynamicMapServiceLayer("http://*******:8399/arcgis/rest/services/prova2/MapServer", null, theToken);
mappa.addLayer(mProt);
}
}


]]>
</mx:Script>

<esri:Map id="mappa">
<esri:ArcGISDynamicMapServiceLayer url="http://*******:8399/arcgis/rest/services/basemap/LyrCantonePolitico/MapServer" />
<!-- this works ... -->
<esri:ArcGISDynamicMapServiceLayer url="http://*******:8399/arcgis/rest/services/prova/MapServer" token="VN3MlX0Tl2sN1rEJv-Qpud-iUkQSRuDjZIznW4JWTY87EqeBwzYD5IY7PjlIJDbQfjNMJi6KPv1PztpF7wjLuQ.."/>
</esri:Map>
</mx:Application>
0 Kudos
CarmenDurham
Occasional Contributor II
Not sure if this will be your answer, but it is something else to try...  This is something that I received from ESRI-Char  about this when I was trying to grab a token programmatically.  I haven't been able to try it yet so I cannot tell you if it works:

From Saurbh at ESRI:

"Ok, the error that I was getting was due to the FlashVersion I have installed.

So, apparently, there is a security issue with Flash 9.0.124 that requires the following line to be added to the CrossDomain.xml file:

<allow-http-request-headers-from domain=�?�*�?� headers=�?�SOAPAction�?�/>

http://dotanything.wordpress.com/2008/08/11/flex-security-error-accessing-url-or-channelsecurityerro...  "

Please let me know if this works for you!

Carmen Durham
City of Greenville, SC
0 Kudos
GiosiaPoma
New Contributor III
Hi Carmen,
thanks for your suggestion. I've tried with your crossdomain.xml idea but with this code nothing works... I use flash 10 with flex 3.5.
I think the problem is in the api, because the generated token works properly if I insert it in the mxml tag and in actionscript normally after it generation (in 2nd time) but if I generate the token on the fly and I add the new token generated return token is invalid (viewed with firebugs).

Others idea?? Thank you 4 all
0 Kudos
GiosiaPoma
New Contributor III
Hi Carmen, 
thanks for your suggestion. I've tried with your crossdomain.xml idea but with this code nothing works... I use flash 10 with flex 3.5. 
I think the problem is in the api, because the generated token works properly if I insert it in the mxml tag and in actionscript normally after it generation (in 2nd time) but if I generate the token on the fly and I add the new token generated return token is invalid (viewed with firebugs). 

Others idea?? Thank you 4 all


Hi everybody,
I've found the problem. I don't know why but I explain you my solution to the problem.

My configuration is ArcGis Server 9.3.1 SP1 Java version with token authentication on ldap server.

Like the code posted above, when I have founded a token I made an alert. In the debug mode I've seen the same string. And my focus wasn't on the token string. This is my big mistake...



To solve the problem with this error code {"error":{"code":498,"message":"Invalid token","details":[]}} I've added a simple trim function before set the theToken variable:
theToken = StringUtil.trim(event.result.toString()); and now work all ok


See my test code:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    xmlns:esri="http://www.esri.com/2008/ags"
    pageTitle="Example - ArcGIS API for Flex connecting to a dynamic secured AGS service"
    initialize="init()">

 <mx:Script>
  <![CDATA[
   import mx.utils.StringUtil;
   import flash.utils.setTimeout;
   import mx.binding.utils.BindingUtils;
   import mx.rpc.http.HTTPService;
   import mx.controls.Alert;
   import mx.rpc.events.ResultEvent;
   import mx.rpc.events.FaultEvent;
   import com.esri.ags.layers.ArcGISDynamicMapServiceLayer;

   private var theToken:String;

   private function init():void {
    var unsecuredBaseMap:ArcGISDynamicMapServiceLayer = new ArcGISDynamicMapServiceLayer("http://******/arcgis/rest/services/*****/MapServer");
    map.addLayer(unsecuredBaseMap);

    RequestToken('ldapUser','ldapPassword');
    }

   public function RequestToken(username:String, password:String):void {
    var http:HTTPService = new HTTPService();
    // register event handlers (resultHandler and faultHandler functions)
    http.addEventListener( ResultEvent.RESULT, tokenResultHandler );
    http.addEventListener( FaultEvent.FAULT, faultHandler );

    http.url = "http://******/arcgis/tokens?request=gettoken&username="+ username +"&password="+ password  +"&clientid=ref.http://******.ti.ch&expiration=1440";

    http.method = "GET";
    http.resultFormat = "text";

    http.send();

    function faultHandler(event:FaultEvent):void
    {
     Alert.show(event.fault.toString());
    }
    function tokenResultHandler(event:ResultEvent):void
    {
     theToken = StringUtil.trim(event.result.toString());
     caricaLayerProtetti();
    }
         }

   private function caricaLayerProtetti():void {
    var protectedMap1:ArcGISDynamicMapServiceLayer = new ArcGISDynamicMapServiceLayer("http://******/arcgis/rest/services/*****/MapServer");
    protectedMap1.token = theToken;
    map.addLayer(protectedMap1);

    var protectedMap2:ArcGISDynamicMapServiceLayer = new ArcGISDynamicMapServiceLayer("http://******/arcgis/rest/services/*****/MapServer");
    protectedMap2.token = theToken;
    map.addLayer(protectedMap2);
   }

  ]]>
 </mx:Script>

 <mx:Label text="Java" fontSize="14"/>
 <esri:Map id="map" />
</mx:Application>
0 Kudos
KathleenBrenkert
Occasional Contributor
I don't yet have an ssl certificate, although I am planning to get that part taken care of soon.  I have used the suggested methods above and at one point "I swear" it was working.  Now that I have programed the rest of my site it has quit working.  I am at Server 10.1.  If I send:
http.url="http://xxxxxxx/arcgis/tokens/arcgis/tokens?request=gettoken&username="+username+"&password="+password;

I get a valid token.  If I add clientid or expiration to this url, I get invalid tokens.  Am I getting invalid tokens b/c I don't yet have the certificate set up? or are the issues with my security settings on the service or server side? or by any chance is this just how it works at 10.1? 

Also, can anyone tell me if I set up the SSL will it affect my nonsecure services.  Or in otherwords, once I get the SSL certificate running is it going to shut down my sites that are not using tokens.  Might seem like a silly question, but I've made assumptions before and I am fumbling through this security stuff.  Thanks in advance!!
0 Kudos