1

Mono for Android 的安全 WCF 服务的状态如何?到 SOAP 1.2 了吗?我正在为一个将与 WCF 服务交互的 Android 应用程序编写 POC,但我正在努力让事情正常工作。

我正在尝试连接到具有TransportWithMessageCredential安全性的服务。但是我在服务器端遇到错误。

这是服务器端错误:

MessageSecurityException:安全处理器无法在消息中找到安全标头。这可能是因为消息是不安全的错误,或者是因为通信双方之间存在绑定不匹配。如果为安全配置了服务并且客户端未使用安全性,则可能会发生这种情况。

服务器配置:

<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>

客户代码:

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;
    }
}

此代码在 WPF 中运行良好,返回结果,一切正常。我从较旧的线程中看到 WCF 仍处于开发周期的早期,但我只是想先检查一下我是否做错了什么。

4

4 回答 4

2

要使您的服务在绑定不匹配的情况下仍能正常工作,您需要修改

<security mode="TransportWithMessageCredential" enableUnsecuredResponse="true"  >
   <message clientCredentialType="UserName" />
 </security>

我已经包含了上面示例中的整个 webconfig 以及添加的更改

 <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" enableUnsecuredResponse="true"  >
        <message clientCredentialType="UserName" />
      </security>
    </binding>
  </basicHttpBinding>
</extensions>
于 2012-05-30T22:15:32.143 回答
2

目前 MonoTouch 不支持 WS-Security 协议,该协议允许客户端在 SOAP 消息信封内发送凭据。但是,MonoTouch 确实支持通过指定适当的 ClientCredentialType 将 HTTP 基本身份验证凭据发送到服务器的能力。

请参阅此页面: http ://docs.xamarin.com/android/guides/Application_Fundamentals/Introduction_to_Web_Services

于 2012-11-01T21:54:21.900 回答
0

我刚刚使用了 RestSharp 和一个将在服务器端进行身份验证的自定义身份验证标头内容。

于 2012-07-05T08:41:28.217 回答
0

在我的情况下,在主机配置文件的 AudienceUris 标记中添加服务修复了相同异常的问题。

<system.identityModel>
...
    <identityConfiguration>
    ...
        <audienceUris>
            <add value="serviceName.svc" />
        </audienceUris>
    ...
    </identityConfiguration>
...
</system.identityModel>
于 2014-12-11T15:47:58.017 回答