Hi,
I would like to use a WFS layer like in this example: https://developers.arcgis.com/net/latest/wpf/sample-code/display-wfs-layer/
but my wfs service requires a login + password authentication and i have no idea how to implement this authentication.
So how to do?
Thanks in advance for all the answers
Cordialement,
Jean-Christophe
Hi Jean-Cristophe. I recommend looking at our security samples for help with authentication workflows. Can you please share information about what type of authentication you're using for your WFS layer?
Zack
Hello Zack,
Authentication type should be Basic : WWW-Authenticate: Basic realm="mapservRLV"
Regards,
jcb
Hello,
In this particular scenario, I would suggest going through Zack's recommendation first to see if that answers your questions.
If you have already tried adding a NetworkCredential with username/password and still the server denies access (does not challenge the client for username/password). I would also suggest trying out the following code if your server implements a HTTP Basic authentication.
private void EagerlyAddNetworkCredentials(object sender, HttpRequestMessage e)
{
var anyCred = Esri.ArcGISRuntime.Security.AuthenticationManager.Current.FindCredential(e.RequestUri, AuthenticationType.NetworkCredential);
if (anyCred is ArcGISNetworkCredential runtimeNetCred)
{
// If a NetworkCredential is found for this request, but we are still waiting to be challenged...
if (!e.Headers.Contains("Authorization"))
{
// Generate an HTTP Basic Authorization header per RFC 2617
var netCred = runtimeNetCred.Credentials.GetCredential(e.RequestUri, "Basic");
var rawCredentialBytes = Encoding.GetEncoding("ISO-8859-1").GetBytes($"{netCred.UserName}:{netCred.Password}");
// Add it to the request
e.Headers.Add("Authorization", $"Basic {Convert.ToBase64String(rawCredentialBytes)}");
}
}
}
//Loads the service
private async void WFSNetworkCred()
{
ArcGISHttpClientHandler.HttpRequestBegin += EagerlyAddNetworkCredentials;
MyView.Map = new Map(Basemap.CreateImagery());
var am = Esri.ArcGISRuntime.Security.AuthenticationManager.Current;
am.AddCredential(new ArcGISNetworkCredential
{
ServiceUri = new Uri("Insert_Service_URL_Here"),
Credentials = new NetworkCredential("username", "password"),
});
var wfs = "Insert_Service_URL_Here";
var wfsService = new WfsService(new Uri(wfs));
await wfsService.LoadAsync();
}
I protected a local GeoServer service with a username and password. Some OGC services do not challenge the clients to log in. The service needs an `Authentication` header present in the request (for ex. Basic authentication header). This scenario forces the clients to `eagerly` send their login info with the request itself and not wait for the challenge to come back.
This is currently not supported in the Runtime SDK. However, a possible workaround could be to tap into the ArcGISHttpClientHandler.HttpRequestBegin Event, forcing it to add our NetworkCredentials with the outgoing requests (like in the code above).
I hope this works for you. Let me know if you face any problems.
Hello Aditya,
Thank you for your useful answer. It seens to work for the network credential.
But i get an other error when opening layer : "Invalid XML.: Parser was expecting WFS_Capabilities."
Could you help me again ?
This is my code (with some confidential information masked) :
private async void Initialize()
{
ArcGISHttpClientHandler.HttpRequestBegin += EagerlyAddNetworkCredentials;
// Create the map with topographic basemap.
MyMapView.Map = new Map(Basemap.CreateTopographic());
try
{
var am = Esri.ArcGISRuntime.Security.AuthenticationManager.Current;
am.AddCredential(new ArcGISNetworkCredential
{
ServiceUri = new Uri("http://x.y.z.1/cgi-bin/mapservRLV.exe?map=D:/GFI/Cartes/client1/Carte4_IA.map"),
Credentials = new NetworkCredential("toto", "titi"),
});
var wfs = "http://x.y.z.1/cgi-bin/mapservRLV.exe?map=D:/GFI/Cartes/client1/Carte4_IA.map&service=WFS&request=GetCapabilities&version=1.1.0";
var wfsService = new Esri.ArcGISRuntime.Ogc.WfsService(new Uri(wfs));
await wfsService.LoadAsync();
...
}
catch (Exception e)
{
MessageBox.Show(e.ToString(), "Couldn't load sample.");
Debug.WriteLine(e);
}
I forget to say that the request with GetCapabilities works in the browser.
Thanks
Hello Jean-Christophe,
My assumption is that the credential is not getting applied to the GetCapabilities url. Maybe try adding another Credential and let the serviceUri be the GetCapabilities url.
I hope this works.
Thanks,
Aditya