Visual Basic (Declaration) | |
---|---|
Public Property TokenGenerationReferer As String |
C# | |
---|---|
public string TokenGenerationReferer {get; set;} |
A referer is text in the Http header that is passed between web requests of the client application and web server.
In many scenarios, the referer is used to provide the web server how the incoming web request was initiated. For example a user clicked a particular hyperlink on a web page and the referer gets populated with that hyperlink. The referer is often the URL of the previous web page from which a link was followed. Some companies use referer information to find out user internet browsing patterns for their internet site. Setting referer information in the Http header of a web request is many times required by secured web sites so they can ensure that only approved users are using their resources.
IMPORTANT
Setting a string value for the IdentityManager.TokenGenerationReferer Property to the correct referer is necessary in order to gain access to ArcGIS Server web services that require long term tokens for authentication. ArcGIS Online and ArcGIS Portal require long term token for web services that are secured. Depending on the development platform, specifying the correct string for the IdentityManager.TokenGenerationReferer Property can be imperative to accessing secured services by the IdentityManager.
In the ArcGIS Runtime SDK for WPF, the referer is not automatically set for the application. You can use the IdentityManager.TokenGenerationRefer Property to provide a mechanism to specify the referer in the Http header of token based secured web pages. It really does not matter what the string value that is used when setting the referer. What is important to know is that the IdentityManager.TokenGenerationReferer Property must be set to some string value in order to access secured services that require long term token (specifically secured services on ArcGIS Online and ArcGIS Portal).
TIP: To see the effect of setting the IdentityManager.TokenGenerationRefer Property, use an internet traffic monitoring application (like Fiddler) to view the Request Headers of the running client application. See the following screen shot of Fiddler for some sample web traffic captured:
Property Value
The default referer.How to use:
When the application loads a backdrop ArcGISTiledMapServiceLayer is displayed. An ArcGISDynamicMapServiceLayer that has Token security is added via XAML and on its first attempt to load it will fail. Then the user is prompted to enter username/password information to generate a Token via the IdentityManager to access the secured layer. A 'Referer' is set as part of the long term Token generation process that will be passed back and forth in the Http WebRequest Headers. NOTE: it is required to supply your own Url to a Token Secured ArcGIS Server MapService Layer. You also need to know your username/passoword to access the Layer.
The XAML code in this example is used in conjunction with the code-behind (C# or VB.NET) to demonstrate the functionality.
The following screen shot corresponds to the code example in this page.
XAML | Copy Code |
---|---|
<Grid x:Name="LayoutRoot" Background="White"> <!-- Add a Map Control. Set its Extent to the North-West US with the Spatial Reference of WKID=102100. FYI: By setting the Map's Extent and SpatialReference explicitly, the ArcGISTiledMapServiceLayer can be displayed instantly without having to wait for the ArcGISDynamicMapServiceLayer to return its SpatialReference information. The SpatialReference information about the ArcGISDynamicMapServiceLayer will not be known until the user supplies the correct username/password for the IdentityManager to get the Token Secured layer. --> <esri:Map Name="MyMap" WrapAround="True" Height="300" Width="500" Margin="0,260,378,0"> <esri:Map.Extent> <esri:Envelope XMin="-13914551" YMin="5620588" XMax="-12870236" YMax="6403824"> <esri:Envelope.SpatialReference> <esri:SpatialReference WKID="102100" /> </esri:Envelope.SpatialReference> </esri:Envelope> </esri:Map.Extent> <!-- Add an unsecured ArcGISTiledMapServiceLayer as a backdrop. --> <esri:ArcGISTiledMapServiceLayer ID="Street Map" Url="http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer"/> <!-- Add a Token Secured ArcGISDynamicMapServiceLayer that you provide. You may also need to adjust the Map.Extent (above) to match the geographic area of your custom dataset. --> <esri:ArcGISDynamicMapServiceLayer ID="Bellevue_Tree_Survey" DisplayName="Bellevue Tree Survey" Url="http://www.YourArcGISServer.com/arcgis/rest/services/TokenSecuredServices/Bellevue_Tree_Survey/MapServer"/> </esri:Map> <!-- Add a MapProgressBar to show that data layers are loading. --> <esri:MapProgressBar x:Name="MyProgressBar" Map="{Binding ElementName=MyMap}" HorizontalAlignment="Center" VerticalAlignment="Center" Width="297" Height="82" Margin="171,210,310,268" /> <!-- Add some controls that display what the Referer is that is being passed to the Http WebRequest Header. --> <Label Height="28" HorizontalAlignment="Left" Margin="0,147,0,0" Name="Label1" VerticalAlignment="Top" Content="IdentityManager.TokenGenerationReferer:"/> <TextBlock Height="23" HorizontalAlignment="Left" Margin="4,172,0,0" Name="TextBlock_IdentityManager_TokenGenerationReferer" Text="TextBlock" VerticalAlignment="Top" /> <Label Height="28" HorizontalAlignment="Left" Margin="0,214,0,0" Name="Label2" VerticalAlignment="Top" Content="IdentityManager.GenerateTokenOptions.Referer:"/> <TextBlock Height="23" HorizontalAlignment="Left" Margin="4,239,0,0" Name="TextBlock_IdentityManager_GenerateTokenOptions_Referer" Text="TextBlock" VerticalAlignment="Top" /> <!-- Add a temporary Grid that disappears when the user has entered the correct username/password for the IdentityManager and the ArcGISDynamicMapServiceLayer has loaded. --> <Grid Name="ShadowGrid" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Background="#66121212"/> <!-- Add controls that will allow for the user to specify a username/password to access the ArcGISDynamicMapServiceLayer. The controls will disappear when the user has entered the correct username/password for the IdentityManager and the ArcGISDynamicMapServiceLayer has loaded. --> <Grid Name="LoginGrid" MaxWidth="250" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,15,15,0" Visibility="Collapsed"> <Rectangle Stroke="Gray" RadiusX="10" RadiusY="10" Fill="LightGray" Margin="-10" > <Rectangle.Effect> <DropShadowEffect/> </Rectangle.Effect> </Rectangle> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <!-- Yes, the password is visible in this example. You could use a PasswordBox instead to mask the password text. --> <TextBlock Name="TitleTextBlock" Grid.Row="0" Grid.ColumnSpan="2" TextWrapping="Wrap" /> <TextBlock Text="Username" Grid.Column="0" Grid.Row="1" Margin="2" VerticalAlignment="Center" /> <!-- Supply your 'YourUserName' in the Text Property! --> <TextBox Name="UserTextBox" Text="YourUserName" HorizontalAlignment="Right" Margin="2" Grid.Column="1" Grid.Row="1" Width="140" /> <TextBlock Text="Password" Grid.Column="0" Grid.Row="2" Margin="2" VerticalAlignment="Center" /> <!-- Supply your 'YourPassword' in the Text Property! --> <TextBox Name="PasswordTextBox" Text="YourPassword" HorizontalAlignment="Right" Margin="2" Grid.Column="1" Grid.Row="2" Width="140" /> <Button Name="LoginLoadLayerButton" Content="Login and Load Layer" Width="140" Margin="0,5,0,5" HorizontalAlignment="Center" Grid.Row="3" Grid.ColumnSpan="2" /> </Grid> </Grid> <!-- Add a LegendControl. --> <Border Name="LegendBorder" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="5" Visibility="Collapsed"> <esri:Legend Map="{Binding ElementName=MyMap}" LayerItemsMode="Tree" Height="300" Margin="406,260,12,0"/> </Border> <!-- Provide the instructions on how to use the sample code. --> <TextBlock Height="129" HorizontalAlignment="Left" Name="TextBlock1" VerticalAlignment="Top" Width="486" TextWrapping="Wrap" Margin="4,12,0,0" Text="When the application loads a backdrop ArcGISTiledMapServiceLayer is displayed. An ArcGISDynamicMapServiceLayer that has Token security is added via XAML and on its first attempt to load it will fail. Then the user is prompted to enter username/password information to generate a Token via the IdentityManager to access the secured layer. A 'Referer' is set as part of the long term Token generation process that will be passed back and forth in the Http WebRequest Headers. NOTE: it is required to supply your own Url to a Token Secured ArcGIS Server MapService Layer. You also need to know your username/passoword to access the Layer." /> </Grid> |
C# | Copy Code |
---|---|
public MainWindow() { InitializeComponent(); // Wire up an Event Handler for when all of the Layer have been initialized in the Map. MyMap.Layers.LayersInitialized += Layers_Initialized; // Set the referer string of the IdentityManager using the .TokenGenrationReferer Property. // This will establish the referer string that is part of the Http WebRequest Header. // FYI: You can view the 'Referer' header information in freeware/shareware applications like 'Fiddler'. // NOTE: // For WPF this value could be any string. Ex: "http://www.MyWebSite.com", "http", "h", "Whatever". // For Silverlight this value should point to the .xap file, but any sub-string will do. Ex: "http://localhost:65121/ClientBin/SL-App.xap", "http", "h". // For Windows Phone this value should point to the application install location on the device, but any sub-string will do. Ex: "file://Applications/Install/868A84BA-237D-4980-BF51-74E193CECCF1/Install/", "file", "f". ESRI.ArcGIS.Client.IdentityManager.Current.TokenGenerationReferer = "http"; // Call the IdentityManager.Challange Method to access the Token based ArcGISDynamicMapServiceLayer. ESRI.ArcGIS.Client.IdentityManager.Current.ChallengeMethod = Challenge; } // Member variable to hold attempts at getting Url for the Token services. private Dictionary<string, int> _MyChallengeAttemptsPerUrl = new Dictionary<string, int>(); private void Challenge(string url, Action<ESRI.ArcGIS.Client.IdentityManager.Credential, Exception> callback, ESRI.ArcGIS.Client.IdentityManager.GenerateTokenOptions options) { // Enable the user to be able to provide username/password information in the controls defined in XAML. LoginGrid.Visibility = System.Windows.Visibility.Visible; // Add display information to the custom login controls. TitleTextBlock.Text = string.Format("Login to access:" + Environment.NewLine + " {0}", url); // Add the Url to the member variable. if (! (_MyChallengeAttemptsPerUrl.ContainsKey(url))) { _MyChallengeAttemptsPerUrl.Add(url, 0); } // Use the IdentityManager to generate a Token for accessing the ArcGISDynamicMapServiceLayer. It will try 3 times to get a Token // before giving up. Once the Token is obtained remove the Event Handler for being able to supply username/password login information. RoutedEventHandler handleClick = null; handleClick = (s, e) => { ESRI.ArcGIS.Client.IdentityManager.Current.GenerateCredentialAsync(url, UserTextBox.Text, PasswordTextBox.Text, (credential, ex) => { _MyChallengeAttemptsPerUrl[url] += 1; if (ex == null || _MyChallengeAttemptsPerUrl[url] == 3) { LoginLoadLayerButton.Click -= handleClick; callback(credential, ex); } }, options); }; // Wire up the Event Handler for when the user enters a username/password to generate a Token. LoginLoadLayerButton.Click += handleClick; // Code logic to handle when the user is entering username/password information in the XAML controls. System.Windows.Input.KeyEventHandler handleEnterKeyDown = null; handleEnterKeyDown = (s, e) => { if (e.Key == System.Windows.Input.Key.Enter) { PasswordTextBox.KeyDown -= handleEnterKeyDown; handleClick(null, null); } }; // Wire up the Event Handler for the user typing information in the username/password controls. PasswordTextBox.KeyDown += handleEnterKeyDown; } private void Layers_Initialized(object sender, System.EventArgs e) { // This function fires when all of the Layers have been added to the Map Control. // Get the LayerCollection from the sender. ESRI.ArcGIS.Client.LayerCollection MyLayerCollection = (ESRI.ArcGIS.Client.LayerCollection)sender; // Loop through each Layer. foreach (ESRI.ArcGIS.Client.Layer MyLayer in MyLayerCollection) { // We are only interested in processing the Token Secured ArcGISDynamicMapServiceLayer. if (MyLayer.ID == "Bellevue_Tree_Survey") { if (MyLayer.InitializationFailure == null) { // We successfully accessed the Token Secured ArcGISDynamicMapServiceLayer. // Make the controls for supplying the username/password as well as the Grid that is covering all of the other controls // in the application dissapear from the screen. LoginGrid.Visibility = System.Windows.Visibility.Collapsed; ShadowGrid.Visibility = System.Windows.Visibility.Collapsed; // Now that the ArcGISDynamicMapServiceLayer is available show the Legend Control. LegendBorder.Visibility = System.Windows.Visibility.Visible; // Two options to see what the IdentityManager is passing to the Http WebRequest Header for the Referer. In both options the // Referer that is being passed is the same information. // Option1: Using IdentityManager.TokenGenerationReferer string WhatIsTheReferer = ESRI.ArcGIS.Client.IdentityManager.Current.TokenGenerationReferer; TextBlock_IdentityManager_TokenGenerationReferer.Text = WhatIsTheReferer; // Option2: Using IdentityManager.GenerateTokenOptions.Referer IEnumerable<ESRI.ArcGIS.Client.IdentityManager.Credential> MyIEnumerableOfCredential = ESRI.ArcGIS.Client.IdentityManager.Current.Credentials; if (MyIEnumerableOfCredential.Count() > 0) { ESRI.ArcGIS.Client.IdentityManager.Credential MyCredentials = MyIEnumerableOfCredential.First(); ESRI.ArcGIS.Client.IdentityManager.GenerateTokenOptions MyIdentityManager_GenerateTokenOptions = MyCredentials.GenerateTokenOptions; string WhatIsTheReferer2 = MyIdentityManager_GenerateTokenOptions.Referer; TextBlock_IdentityManager_GenerateTokenOptions_Referer.Text = WhatIsTheReferer2; } } else { // There was a problem accessing the Token Secured ArcGISDynamicMapServiceLayer. MessageBox.Show(MyLayer.InitializationFailure.Message); } } } } |
VB.NET | Copy Code |
---|---|
Public Sub New() InitializeComponent() ' Wire up an Event Handler for when all of the Layer have been initialized in the Map. AddHandler MyMap.Layers.LayersInitialized, AddressOf Layers_Initialized ' Set the referer string of the IdentityManager using the .TokenGenrationReferer Property. ' This will establish the referer string that is part of the Http WebRequest Header. ' FYI: You can view the 'Referer' header information in freeware/shareware applications like 'Fiddler'. ' NOTE: ' For WPF this value could be any string. Ex: "http://www.MyWebSite.com", "http", "h", "Whatever". ' For Silverlight this value should point to the .xap file, but any sub-string will do. Ex: "http://localhost:65121/ClientBin/SL-App.xap", "http", "h". ' For Windows Phone this value should point to the application install location on the device, but any sub-string will do. Ex: "file://Applications/Install/868A84BA-237D-4980-BF51-74E193CECCF1/Install/", "file", "f". ESRI.ArcGIS.Client.IdentityManager.Current.TokenGenerationReferer = "http" ' Call the IdentityManager.Challange Method to access the Token based ArcGISDynamicMapServiceLayer. ESRI.ArcGIS.Client.IdentityManager.Current.ChallengeMethod = AddressOf Challenge End Sub ' Member variable to hold attempts at getting Url for the Token services. Private _MyChallengeAttemptsPerUrl As Dictionary(Of String, Integer) = New Dictionary(Of String, Integer)() Private Sub Challenge(ByVal url As String, ByVal callback As Action(Of ESRI.ArcGIS.Client.IdentityManager.Credential, Exception), ByVal options As ESRI.ArcGIS.Client.IdentityManager.GenerateTokenOptions) ' Enable the user to be able to provide username/password information in the controls defined in XAML. LoginGrid.Visibility = System.Windows.Visibility.Visible ' Add display information to the custom login controls. TitleTextBlock.Text = String.Format("Login to access:" + Environment.NewLine + " {0}", url) ' Add the Url to the member variable. If (Not _MyChallengeAttemptsPerUrl.ContainsKey(url)) Then _MyChallengeAttemptsPerUrl.Add(url, 0) End If ' Use the IdentityManager to generate a Token for accessing the ArcGISDynamicMapServiceLayer. It will try 3 times to get a Token ' before giving up. Once the Token is obtained remove the Event Handler for being able to supply username/password login information. Dim handleClick As RoutedEventHandler = Nothing handleClick = Sub(s, e) ESRI.ArcGIS.Client.IdentityManager.Current.GenerateCredentialAsync(url, UserTextBox.Text, PasswordTextBox.Text, Sub(credential, ex) _MyChallengeAttemptsPerUrl(url) += 1 If ex Is Nothing OrElse _MyChallengeAttemptsPerUrl(url) = 3 Then RemoveHandler LoginLoadLayerButton.Click, handleClick callback(credential, ex) End If End Sub _ , options) End Sub ' Wire up the Event Handler for when the user enters a username/password to generate a Token. AddHandler LoginLoadLayerButton.Click, handleClick ' Code logic to handle when the user is entering username/password information in the XAML controls. Dim handleEnterKeyDown As System.Windows.Input.KeyEventHandler = Nothing handleEnterKeyDown = Sub(s, e) If e.Key = System.Windows.Input.Key.Enter Then RemoveHandler PasswordTextBox.KeyDown, handleEnterKeyDown handleClick(Nothing, Nothing) End If End Sub ' Wire up the Event Handler for the user typing information in the username/password controls. AddHandler PasswordTextBox.KeyDown, handleEnterKeyDown End Sub Private Sub Layers_Initialized(sender As System.Object, e As System.EventArgs) ' This function fires when all of the Layers have been added to the Map Control. ' Get the LayerCollection from the sender. Dim MyLayerCollection As ESRI.ArcGIS.Client.LayerCollection = sender ' Loop through each Layer. For Each MyLayer As ESRI.ArcGIS.Client.Layer In MyLayerCollection ' We are only interested in processing the Token Secured ArcGISDynamicMapServiceLayer. If MyLayer.ID = "Bellevue_Tree_Survey" Then If MyLayer.InitializationFailure Is Nothing Then ' We successfully accessed the Token Secured ArcGISDynamicMapServiceLayer. ' Make the controls for supplying the username/password as well as the Grid that is covering all of the other controls ' in the application dissapear from the screen. LoginGrid.Visibility = System.Windows.Visibility.Collapsed ShadowGrid.Visibility = System.Windows.Visibility.Collapsed ' Now that the ArcGISDynamicMapServiceLayer is available show the Legend Control. LegendBorder.Visibility = System.Windows.Visibility.Visible ' Two options to see what the IdentityManager is passing to the Http WebRequest Header for the Referer. In both options the ' Referer that is being passed is the same information. ' Option1: Using IdentityManager.TokenGenerationReferer Dim WhatIsTheReferer As String = ESRI.ArcGIS.Client.IdentityManager.Current.TokenGenerationReferer TextBlock_IdentityManager_TokenGenerationReferer.Text = WhatIsTheReferer ' Option2: Using IdentityManager.GenerateTokenOptions.Referer Dim MyIEnumerableOfCredential As IEnumerable(Of ESRI.ArcGIS.Client.IdentityManager.Credential) = ESRI.ArcGIS.Client.IdentityManager.Current.Credentials If MyIEnumerableOfCredential.Count > 0 Then Dim MyCredentials As ESRI.ArcGIS.Client.IdentityManager.Credential = MyIEnumerableOfCredential(0) Dim MyIdentityManager_GenerateTokenOptions As ESRI.ArcGIS.Client.IdentityManager.GenerateTokenOptions = MyCredentials.GenerateTokenOptions Dim WhatIsTheReferer2 As String = MyIdentityManager_GenerateTokenOptions.Referer TextBlock_IdentityManager_GenerateTokenOptions_Referer.Text = WhatIsTheReferer2 End If Else ' There was a problem accessing the Token Secured ArcGISDynamicMapServiceLayer. MessageBox.Show(MyLayer.InitializationFailure.Message) End If End If Next End Sub |
Target Platforms: Windows XP Professional, Windows Server 2003 family, Windows Vista, Windows Server 2008 family, Windows 7, Windows 8