1

建筑学

我有一个简单的示例 Web 服务,它通过 ServiceContract 和 OperationContract 公开两个操作,没什么特别的。此服务应由 Adob​​e Flex 4 客户端使用。不幸的是,Flex 只能处理 SOAP 1.1(而不是 SOAP 1.2),所以我必须在 WCF端使用BasicHttpBinding 。为了保护对 Web 服务的访问,我必须使用基本身份验证,因为它是双方(WCFFlex)都能理解的唯一身份验证方法。基本身份验证与 SSL 一起加密传输。我使用 Visual Studio 2012 在 IIS Express 中运行该服务。

WCF 服务配置

网页配置

<system.serviceModel>

<services>
  <service name="UserAuthentication.AuthenticationService"
           behaviorConfiguration="AuthenticationServiceBehavior">
    <endpoint address=""
              binding="basicHttpBinding"
              bindingConfiguration="AuthenticationBinding"
              contract="UserAuthentication.IAuthenticationService" />
    <endpoint contract="IMetadataExchange"
              binding="mexHttpBinding"
              address="mex" />
  </service>
</services>

<bindings>
  <basicHttpBinding>
    <binding name="AuthenticationBinding" maxReceivedMessageSize="65536">
        <!-- Use SSL (Transport) and MessageCredential by Username (referencing behaviors/serviceBehaviors/behavior/serviceCredentials) -->
        <security mode="TransportWithMessageCredential">
            <transport clientCredentialType="None" proxyCredentialType="None" />
            <message clientCredentialType="UserName" />
        </security>
      <readerQuotas maxArrayLength="65536" maxBytesPerRead="65536" maxStringContentLength="65536"/>
    </binding>
  </basicHttpBinding>
</bindings>

<behaviors>
  <serviceBehaviors>
    <behavior name="AuthenticationServiceBehavior">
      <serviceDebug includeExceptionDetailInFaults="false" />
      <serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" />
      
      <!-- Use Custom DistributorValidator for Basic Authentication -->
      <serviceCredentials>
        <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="UserAuthentication.DistributorValidator,UserAuthentication"/>
        <!--<serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />-->
      </serviceCredentials>
      
      <!-- For Debug purpose: @see http://intrepiddeveloper.wordpress.com/2008/08/07/security-event-logging-auditing/ -->
      <serviceSecurityAudit auditLogLocation="Application" serviceAuthorizationAuditLevel="Failure" messageAuthenticationAuditLevel="Failure" suppressAuditFailure="true"/>
    </behavior>
  </serviceBehaviors>
</behaviors>

</system.serviceModel>

分布式验证器.cs

应该用于通过基本身份验证中的用户名和密码对用户进行身份验证。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ServiceModel;
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;

namespace UserAuthentication
{
    public class DistributorValidator : UserNamePasswordValidator
    {
        /* Throw exeption to deny access for user */
        public override void Validate(string userName, string password)
        {
            if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(password))
                throw new SecurityTokenException("Username and password required");

            if( userName.Equals("user") == false || password.Equals("secretpwd") == false)
                throw new FaultException(string.Format("Wrong username ({0}) or password ", userName));
        }

    }
}

在 IIS Express 中使用 SSL 启动服务

  1. 在解决方案资源管理器中选择项目按 F4 打开属性面板
  2. 将属性SSL 启用设置为 True
  3. 要运行项目,请按 F11(页面的 HTTP 版本应在浏览器中打开)
  4. 右键单击任务栏托盘中的 IIS Express 图标,然后选择页面的 HTTPS 版本
  5. 您现在可以通过 HTTPS 打开服务的 WSDL 文件

使用 Flex 使用 Web 服务

按照Adob​​e 文档中的说明连接到 Web 服务。到目前为止,这工作正常,并且该服务已在Flash Builder的“数据/服务”面板中创建。

问题

通过 Flash Builder 中的测试操作面板测试 Web 服务,结果是来自 HTML 源代码,https://localhost:44301/AuthenticationService.svc而不是预期的 SOAP 消息。

尝试与免费版SoapUI相同的 Web 服务和操作,结果是这个 SOAP 信封:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
   <s:Body>
      <s:Fault>
         <faultcode xmlns:a="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">a:InvalidSecurity</faultcode>
         <faultstring xml:lang="de-AT">An error occurred when verifying security for the message.</faultstring>
      </s:Fault>
   </s:Body>
</s:Envelope>

此外,Windows 事件查看器中还会记录MessageSecurityException :

 Message authentication failed.
 Service: https://localhost:44301/AuthenticationService.svc
 Action: http://tempuri.org/IAuthenticationService/GetData
 ClientIdentity: 
 ActivityId: <null>
 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.

在这两种情况下(Flex 和 SoapUI),自定义的 DistributorValidator 都不会被触及,因此问题更深地在于 WCF 的魔力。

问题

是否有可能运行带有 BasicHttpBinding 和 Basic Authentication 的 WCF 服务,与 Adob​​e Flex 配合得很好?

4

1 回答 1

0

您需要弄乱标头才能使基本的 HTTP 身份验证与 HTTPService 一起使用。

从 Flex 拨打电话时,它看起来像这样......

var encoder:Base64Encoder = new Base64Encoder();
encoder.insertNewLines = false; // or else your header may fail...
encoder.encode("user_name:user_pass");
service.headers = {Authorization:"Basic " + encoder.toString()};                                                
service.send();  //where servie is an instance of HTTPService
于 2013-09-18T22:46:30.907 回答