建筑学
我有一个简单的示例 Web 服务,它通过 ServiceContract 和 OperationContract 公开两个操作,没什么特别的。此服务应由 Adobe Flex 4 客户端使用。不幸的是,Flex 只能处理 SOAP 1.1(而不是 SOAP 1.2),所以我必须在 WCF端使用BasicHttpBinding 。为了保护对 Web 服务的访问,我必须使用基本身份验证,因为它是双方(WCF和Flex)都能理解的唯一身份验证方法。基本身份验证与 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 启动服务
- 在解决方案资源管理器中选择项目按 F4 打开属性面板
- 将属性SSL 启用设置为 True
- 要运行项目,请按 F11(页面的 HTTP 版本应在浏览器中打开)
- 右键单击任务栏托盘中的 IIS Express 图标,然后选择页面的 HTTPS 版本
- 您现在可以通过 HTTPS 打开服务的 WSDL 文件
使用 Flex 使用 Web 服务
按照Adobe 文档中的说明连接到 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 服务,与 Adobe Flex 配合得很好?