This sample demonstrates how to prompt the user for a username and password to authenticate with ArcGIS Server to access an ArcGIS token-secured service. Accessing secured services requires a login that's been defined on the server.
Use case
Your app may need to access services that are restricted to authorized users. For example, your organization may host ArcGIS services that are only accessible by verified users.
How to use the sample
When you run the sample, the app will load a map that contains a layer from a secured service. Then, you will be challenged for a user name and password to view that layer. Enter the correct user name (user1) and password (user1). If you authenticate successfully, the secured layer will display, otherwise the map will contain only the public layers.
How it works
- A custom
ChallengeHandler
is set forAuthenticationManager
that displays a login dialog for entering a username and password. - In response to the attempt to access secured content, the
AuthenticationManager
calls the challenge handler. - A
TokenCredential
is created from the entered username and password, and an attempt is made to load the layer.
Relevant API
- AuthenticationManager
- TokenCredential
Additional information
Please note: the username and password are case sensitive for token-based authentication. If the user doesn't have permission to access all the content within the portal item, partial or no content will be returned.
Tags
authentication, cloud, portal, remember, security
Sample Code
<UserControl x:Class="ArcGISRuntime.WinUI.Samples.TokenSecuredChallenge.TokenSecuredChallenge"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:esriUI="using:Esri.ArcGISRuntime.UI.Controls"
xmlns:local="using:ArcGISRuntime.WinUI.Samples.TokenSecuredChallenge">
<UserControl.Resources>
<local:LoadStatusToColorConverter x:Key="StatusToColor" />
</UserControl.Resources>
<Grid x:Name="layoutGrid">
<esriUI:MapView x:Name="MyMapView" />
<!-- Layer listing with status -->
<Border Style="{StaticResource BorderStyle}">
<StackPanel>
<TextBlock Margin="4"
FontSize="14"
FontWeight="Bold"
Text="Map Layers (with status)"
TextAlignment="Center" />
<StackPanel x:Name="PublicLayerPanel"
Margin="10,5"
Orientation="Horizontal">
<TextBlock Text="{Binding Name}" />
<TextBlock Margin="10,0"
Foreground="{Binding LoadStatus, Converter={StaticResource StatusToColor}}"
Text="{Binding LoadStatus}" />
</StackPanel>
<StackPanel x:Name="SecureLayerPanel"
Margin="10,5"
Orientation="Horizontal">
<TextBlock Text="{Binding Name}" />
<TextBlock Margin="10,0"
Foreground="{Binding LoadStatus, Converter={StaticResource StatusToColor}}"
Text="{Binding LoadStatus}" />
</StackPanel>
</StackPanel>
</Border>
<!-- Login UI -->
<Border x:Name="loginPanel"
HorizontalAlignment="Left"
Style="{StaticResource BorderStyle}"
Visibility="Collapsed">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0"
Grid.Column="0"
Grid.ColumnSpan="2"
Margin="0,0,0,8"
Text="{Binding ServiceUrl}"
TextWrapping="Wrap" />
<TextBlock Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
Margin="0,0,0,8"
FontWeight="SemiBold"
Text="Username and Password are user1/user1"
TextWrapping="Wrap" />
<TextBlock Grid.Row="2"
Grid.Column="0"
Margin="2"
VerticalAlignment="Center"
Text="Username" />
<TextBox Grid.Row="2"
Grid.Column="1"
Margin="2"
Text="{Binding UserName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Grid.Row="3"
Grid.Column="0"
Margin="2"
VerticalAlignment="Center"
Text="Password" />
<!--
For simplicity, the password is visible in this example. You can use a PasswordBox to mask the password text,
but it complicates data binding. See this discussion for details: http://stackoverflow.com/questions/1483892/how-to-bind-to-a-passwordbox-in-mvvm
-->
<TextBox Grid.Row="3"
Grid.Column="1"
Margin="2"
Text="{Binding Password, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<Button Grid.Row="4"
Grid.Column="0"
Grid.ColumnSpan="2"
Margin="0,12,0,0"
HorizontalAlignment="Stretch"
Click="LoginButtonClick"
Content="Login and load layer" />
<TextBlock x:Name="ErrorMessageTextBlock"
Grid.Row="5"
Grid.Column="0"
Grid.ColumnSpan="2"
Margin="8,12,8,0"
Foreground="Red"
Text="{Binding ErrorMessage}"
TextWrapping="Wrap" />
</Grid>
</Border>
</Grid>
</UserControl>