我创建了一个简单的 WCF 服务,我希望可以通过 https 访问它。 WCF 服务使用 UserNamePasswordValidator、customBinding 和 UserNameOverTransport 作为身份验证模式。我在 IIS7.5 中运行它,我在其中创建了自签名服务器证书。
我尝试使用 Silverlight 4 应用程序连接到该服务。我在 Silverlight 4 应用程序中创建了一个服务引用,VS 2010 会自动创建所需的代码(因此显然它能够连接到该服务并获取信息)。
当我调用 WCF 时,我收到一个 SecurityException,但没有任何有关原因的信息。
我让提琴手跑来看看发生了什么。
GET https://my.server:8099/clientaccesspolicy.xml404 未找到(文本/html)
GET https://my.server:8099/crossdomain.xml200 确定(文本/xml)
因此,crossdomain.xml 的 GET 似乎是对服务器的最后一次调用。
crossdomain.xml 如下所示:
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-access-from domain="*" />
<allow-http-request-headers-from domain="*" headers="*" />
</cross-domain-policy>
当在客户端上调用 base.EndInvoke(...) 且 ExceptionMessage 如下时,会发生异常:
{System.Security.SecurityException ---> System.Security.SecurityException: Sicherheitsfehler
bei System.Net.Browser.BrowserHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)
位于 System.Net.Browser.BrowserHttpWebRequest.c_DisplayClass5.b_4(对象发送状态)
位于 System.Net.Browser.AsyncHelper.c_显示类2.b_0(对象发送状态)
--- 实习结束 ---
bei System.Net.Browser.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod,对象状态)
是 System.Net.Browser.BrowserHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
是 System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelAsyncRequest.CompleteGetResponse(IAsyncResult 结果)}
这是我的用户名密码验证器。请注意,出于调试原因,其中包括一个记录器。奇怪的是,记录器从不写任何东西,所以看起来验证函数甚至没有被调用。
namespace ServiceConfiguratorDataSource
{
public class UserCredentialsValidator : UserNamePasswordValidator
{
public override void Validate(string userName, string password)
{
if (userName != "xyz" || password != "xyz")
{
logging.Logger.instance.StatusRoutine("LogOn Error: " + userName);
throw new FaultException("Credentials are invalid");
}
else
{
logging.Logger.instance.StatusRoutine("LogOn Success: " + userName);
}
}
}
}
这是我的 WCF 服务的 Web.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="ServiceConfiguratorDataSource.Service" behaviorConfiguration="ServiceConfiguratorDataSourceBehaviour">
<endpoint address="" binding="customBinding" bindingConfiguration="ServiceConfiguratorCustomBinding" contract="ServiceConfiguratorDataSource.IService" />
</service>
</services>
<bindings>
<customBinding>
<binding name="ServiceConfiguratorCustomBinding">
<security authenticationMode="UserNameOverTransport"></security>
<binaryMessageEncoding></binaryMessageEncoding>
<httpsTransport/>
</binding>
</customBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceConfiguratorDataSourceBehaviour">
<serviceMetadata httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="ServiceConfiguratorDataSource.UserCredentialsValidator,ServiceConfiguratorDataSource" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
这里是 ServiceReferences.ClientConfig
<configuration>
<system.serviceModel>
<bindings>
<customBinding>
<binding name="CustomBinding_IService">
<security authenticationMode="UserNameOverTransport" includeTimestamp="true">
<secureConversationBootstrap />
</security>
<binaryMessageEncoding />
<httpsTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="https://my.server:8099/ServiceConfiguratorDataSource/Service.svc" binding="customBinding" bindingConfiguration="CustomBinding_IService" contract="WCFDataProvider.IService" name="CustomBinding_IService" />
</client>
</system.serviceModel>
</configuration>
我不知道问题的原因可能是什么。
提前致谢,
Frank