What is the state of Mono for Android’s secure WCF services? Is it up to SOAP 1.2 yet?
I am writing a POC for an Android app that will interact with WCF services, but am struggling to get the thing working.
I am trying to connect to a service that has TransportWithMessageCredential security. However I am getting an error on the server side.
This is the server side error:
MessageSecurityException: Security processor was unable to find a
security header in the message. This might be because the message is
an unsecured fault or because there is a binding mismatch between the
communicating parties. This can occur if the service is configured for
security and the client is not using security.
Server Config:
<service name="BrandDirector.ApplicationServer.Core.Services.UI.Products.Specifications.IngredientService"
behaviorConfiguration="CredentialValidation">
<endpoint address="/BasicHttp"
binding="basicHttpBinding"
bindingConfiguration="BDBasicHttpBindingWithSecurity"
contract="BrandDirector.ApplicationServer.Core.Services.UI.Products.Specifications.IIngredientService" />
<endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" />
</service>
<behavior name="CredentialValidation">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<HttpStatusCode200Behavior />
<serviceCredentials type="BrandDirector.ApplicationServer.Core.Security.Authentication.PasswordServiceCredentials, BrandDirector.ApplicationServer.Core.Security, Version=1.0.0.0, Culture=neutral">
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="BrandDirector.ApplicationServer.Core.Security.CredentialValidator, BrandDirector.ApplicationServer.Core.Security" />
</serviceCredentials>
</behavior>
<extensions>
<behaviorExtensions>
<add name="HttpStatusCode200Behavior" type="BrandDirector.ApplicationServer.Core.Services.Common.ServiceModel.HttpStatusCode200BehaviorExtension, BrandDirector.ApplicationServer.Core.Services.Common" />
</behaviorExtensions>
<basicHttpBinding>
<binding name="BDBasicHttpBindingWithSecurity" messageEncoding="Text" maxReceivedMessageSize="655536">
<security mode="TransportWithMessageCredential" >
<message clientCredentialType="UserName" />
</security>
</binding>
</basicHttpBinding>
</extensions>
Client Code:
public class Activity1 : Activity
{
private Button button;
const string address = "https://.../IngredientService.svc/BasicHttp";
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
var timeout = new TimeSpan(0, 1, 0);
var binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportWithMessageCredential)
{
MessageEncoding = WSMessageEncoding.Text,
Security =
{
Transport =
{
ClientCredentialType = HttpClientCredentialType.None,
ProxyCredentialType = HttpProxyCredentialType.None
},
Message =
{
ClientCredentialType = BasicHttpMessageCredentialType.UserName,
}
},
HostNameComparisonMode = HostNameComparisonMode.StrongWildcard,
MaxReceivedMessageSize = 655536,
ReaderQuotas = new System.Xml.XmlDictionaryReaderQuotas
{
MaxArrayLength = 655536,
MaxStringContentLength = 655536,
},
SendTimeout = timeout,
OpenTimeout = timeout,
ReceiveTimeout = timeout,
};
System.Net.ServicePointManager.ServerCertificateValidationCallback += OnServerCertificateValidationCallback;
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
// Get our button from the layout resource,
// and attach an event to it
button = FindViewById<Button>(Resource.Id.MyButton);
button.Click += delegate
{
client = new IngredientServiceClient(binding, new EndpointAddress(address));
var clientCredential = client.ClientCredentials.UserName;
clientCredential.UserName = "admin";
clientCredential.Password = "KDNSG7";
client.BeginGetIngredients("e", callBack, null);
};
}
IngredientServiceClient client;
private void callBack(IAsyncResult ar)
{
var result = client.EndGetIngredients(ar);
button.Text = result.First().Name;
}
private bool OnServerCertificateValidationCallback(object sender, X509Certificate certificate,
X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return true;
}
}
This code works fine in WPF, the result is returned and all is well. I see from older threads that the WCF is still early in the development cycle, but I just want to check if maybe I am doing something wrong first.
I just used RestSharp and a custom authentication header contents that would be authenticated on the server side.