Select to view content in your preferred language

Can't get token for secure services.

4220
9
09-26-2011 06:22 AM
StacieMcGahey
Deactivated User
I'm having trouble programmatically retrieving a token to access secure services.  I have used several examples and they all give me the same result, so I'm assuming the issue is with my request string.  The URL of the site where I manually retrieve tokens is
http://lidar.gis.halff.com/Centaur/tokens/gettoken.html.  So how do I put that in this:
string tokenurl =
                string.Format("https://myserver/arcgis/tokens?request=getToken&username={0}&password={1}&timeout={2}", 
                username, password, timeout);


form to get a token?

This is what I have which is obviously wrong:
tring tokenurl =
                string.Format("http://lidar.gis.halff.com/Centaur/tokens/gettoken.html?request=getToken&username={0}&password={1}&timeout={2}",
                username, password, timeout);


This is the code example I'm currently using from the ESRI Silverlight/WPF Blog:

 ArcGISDynamicMapServiceLayer layer = new ArcGISDynamicMapServiceLayer()
            {
                Url = "http://barn.halff.com/Centaur/rest/services/Lubbock/Lubbock_SW_WebMap_v10b/MapServer",
                ID = "Lubbock SW"                
            };

            layer.InitializationFailed += layer_InitializationFailed;
            ConfigureLayerWithToken(layer);

   void layer_InitializationFailed(object sender, EventArgs e)
        { }

        private void ConfigureLayerWithToken(ArcGISDynamicMapServiceLayer layer)
        {
            string tokenurl =
                string.Format("http://lidar.gis.halff.com/Centaur/tokens/gettoken.html?request=getToken&username={0}&password={1}&timeout={2}",
                username, password, timeout);

            WebClient tokenService = new WebClient();
            tokenService.DownloadStringCompleted += (sender, args) =>
            {
                theToken = args.Result;
                MessageBox.Show(theToken);
                layer.Token = theToken;
                string originalUrl = layer.Url;
                if (Map.Layers.Contains(layer))
                {
                    layer.Url = null;
                    layer.Url = originalUrl;
                }
                else
                    Map.Layers.Add(layer);
            };

            tokenService.DownloadStringAsync(new Uri(tokenurl));
        }


Any help as to what I'm doing wrong would be greatly appreciated, Thanks!
0 Kudos
9 Replies
dotMorten_esri
Esri Notable Contributor
You say you always get the same result, but you never say what that result is. Are you getting an error? The same response? Is the code not compiling? etc...
0 Kudos
StacieMcGahey
Deactivated User
I don't get an error, just no token.  When I add:
MessageBox.Show(theToken);

I get:


Etc..etc...

It looks to me like the code for the page itself.
0 Kudos
DominiqueBroux
Esri Frequent Contributor
string tokenurl =
string.Format("http://lidar.gis.halff.com/Centaur/tokens/gettoken.html?request=getToken&username={0}&password={1}&t...}",
username, password, timeout);


Try without '/gettoken.html' at the end of your URL.
Someting like :
 
string tokenurl =
string.Format("http://lidar.gis.halff.com/Centaur/tokens?request=getToken&username={0}&password={1}&timeout={2}",
username, password, timeout);
 
0 Kudos
StacieMcGahey
Deactivated User
I tried that and every combination I could think of these last couple of days and could never get it to work.  But, for kicks, I tried it one last time and of course if worked.  I hate computers.  Thanks for the help.
0 Kudos
StacieMcGahey
Deactivated User
I found out what my problem was.  I had an "&" in my password.  I had switched to using someone elses login, and that is why it suddenly worked.  Is there any way to work around that?  That is a valid character for a password, and I had no idea it would cause issues when programming at the time.  How do you keep users from choosing that character?  Do you just have to specify to users that it shouldn't be used?  Are there any other characters to worry about?
0 Kudos
DominiqueBroux
Esri Frequent Contributor
You get an error because your token rest end point doesn't accept the GET method.
You have to use the POST method.
0 Kudos
DominiqueBroux
Esri Frequent Contributor
I tried the code posted here in this article but the code doesn't compile as Silverlight is Async and the WebRequest class does not support :GetResponse().

Silverlight doesn't support synchronous method.

Here is an example of code getting the token with asynchronous method and the HTTP POST method:

 
public void GetTokenAsync()
{
  WebClient wc = new WebClient();
  wc.UploadStringCompleted += (s, e) => MessageBox.Show(e.Error == null ? "Token = " + e.Result : "Error = " + e.Error.Message);
  wc.Headers["Content-Type"] = "application/x-www-form-urlencoded";
  string data = EncodeParameter("request", "getToken");
  data += EncodeParameter("username", "staff1");
  data += EncodeParameter("password", "staff1#1");
  wc.UploadStringAsync(new Uri("http://50.19.243.162/arcgis/tokens/"), data);
}
private static string EncodeParameter(string name, string value)
{
  return name + "=" + System.Windows.Browser.HttpUtility.UrlEncode(value) + "&";
}
0 Kudos
DominiqueBroux
Esri Frequent Contributor
can I assume the origional poster was using WPF to get a token via code and the example in this blog post is about WPF and Rex's comment on 6-Mar-2011 confirms that this will not work in Silverlight.
http://blogs.esri.com/Dev/blogs/silv...-services.aspx

No, it should work with Silverlight.
In the comment you point out, Rex said that this will not work in WPF, he is not talking about SL(and anyway he is talking about the 401 stuff not about the mean to get a token).

What I meant was :
     1) in SL you can't use synchronous methods to get a token (just because these methods don't exist)
     2) depending on your service, some token rest end points don't accept a HTTP GET method encoding the parameters in the URL(including the password) . So using a HTTP POST method is more secure.
0 Kudos
DominiqueBroux
Esri Frequent Contributor
When it is time to move to production, the plan is to use HTTPS.

The code to get a token will work the same way with HTTPS.
Nevertheless note that if your application is hosted on HTTP and your services on HTTPS, you may run into cross sheme issues (see this post).
So I would recommend serious tests with the target configuration before moving to production.


If generating a token in Silverlight, the user name and password will be visible on the client, even over an HTTPS connection. In most cases, you'll want to store credentials in a server-side resource (for example, proxy page) and direct requests for token secured services through the server resource.

Both options are possible depending on your process, your can either store credentials in a server side resource or challenge user/password at the client side.
0 Kudos