我试着理解WCF中的身份验证是如何工作的。有一个https端点的自托管服务,它绑定到我的一个证书。
时一切正常
security mode="None"
然后即使在不同的机器上它也能正常工作。与
相同的情况
mode="Transport" and <transport clientCredentialType="None"/>
。当我尝试通过UserName添加验证时,它工作正常,但只在localhost上,当托管在不同的机器上时,我收到错误:
“从其他人那里收到了一个无担保或不正确的安全故障 党......“
为什么不能使用UserName密码验证?
EDIT2:我发现在服务器上抛出以下异常并捕获(但仅限在不同的计算机上):“安全时间戳无效,因为它的创建时间('2014-11-29T01:30:48.824Z')是在将来。当前时间是'2014-11-28T14:51:52.704Z'并允许时钟偏差是'00:05:00'。“我不知道这个创作时间在哪里,但肯定不是来自另一台机器。会发生什么?
第二个问题是关于证书。托管https并将地址绑定到证书时,此证书是否应该作为受信任的客户端计算机安装? (我用 netsh 绑定它) 没有以下代码,我无法连接到我的wcf服务:
System.Net.ServicePointManager.ServerCertificateValidationCallback =
((sender, certificate, chain, sslPolicyErrors) => true);
是客户端的证书验证吗?它检查它是否存在以及它是否由受信任的发行者发布?
编辑: 附加问题: 当我尝试使用浏览器进入服务安全端点时,它表示此连接不安全,不受信任的来源等。在我的服务机器上,我将证书绑定到https,证书是MyCertificate,由“CertificateIssuer”颁发。现在我在服务和客户端机器上安装了颁发者证书 - 我的意思是“CertificateIssuer”进入“受信任的根证书颁发机构”“当我从同一台机器进入时,我仍然不是可靠的事件。我应该如何配置它才能被信任?
服务器配置:
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>
</appSettings>
<system.web>
<compilation debug="true"/>
</system.web>
<!-- When deploying the service library project, the content of the config file must be added to the host's
app.config file. System.Configuration does not support config files for libraries. -->
<system.diagnostics>
<trace autoflush="true"/>
<sources>
<source name="System.ServiceModel" switchValue="Information, ActivityTracing" propagateActivity="true">
<listeners>
<add name="sdt" type="System.Diagnostics.XmlWriterTraceListener" initializeData="SdrConfigExample.e2e"/>
</listeners>
</source>
</sources>
</system.diagnostics>
<system.serviceModel>
<services>
<service name="WcfService1.TestService" behaviorConfiguration="ServiceUsernameValidation">
<host>
<baseAddresses>
<add baseAddress="https://localhost:8734/Services/"/>
<add baseAddress="http://localhost:8735/Wsdl/"/>
</baseAddresses>
</host>
<!-- Service Endpoints -->
<!-- Unless fully qualified, address is relative to base address supplied above -->
<endpoint address="Test" binding="basicHttpBinding" contract="WcfService1.ITestService">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
-->
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
<!-- Metadata Endpoints -->
<!-- The Metadata Exchange endpoint is used by the service to describe itself to clients. -->
<!-- This endpoint does not use a secure binding and should be secured or removed before deployment -->
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information,
set the values below to false before deployment -->
<serviceMetadata httpsGetEnabled="True"/>
<!-- To receive exception details in faults for debugging purposes,
set the value below to true. Set to false before deployment
to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="False"/>
</behavior>
<behavior name="ServiceUsernameValidation">
<serviceMetadata httpsGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="False"/>
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WcfSecurity.PasswordValidator,WcfSecurity"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding>
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
</system.serviceModel>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>
客户端配置:
<?xml version="1.0"?>
<configuration>
<system.diagnostics>
<trace autoflush="true"/>
<sources>
<source name="System.ServiceModel" switchValue="Information, ActivityTracing" propagateActivity="true">
<listeners>
<add name="sdt" type="System.Diagnostics.XmlWriterTraceListener" initializeData="SdrConfigExample.e2e"/>
</listeners>
</source>
</sources>
</system.diagnostics>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_ITestService">
<security mode="TransportWithMessageCredential" >
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://175.28.233.153:8734/Services/Test" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_ITestService" contract="ServiceReference1.ITestService"
name="BasicHttpBinding_ITestService" />
</client>
</system.serviceModel>
</configuration>
服务器代码:
ServiceHost host = new ServiceHost(typeof(TestService));
var uri = host.Description.Endpoints[0].Address.Uri;
var cert = FindCertificate("CN=MyCertificate");
if (!ReserveAddressForHttps(uri.Host, uri.Port, cert, 5000))
{
throw new Exception("Failed to assign service certificate into local interface.");
}
host.Open();
host.Description.Endpoints.ToList().ForEach(x => Console.WriteLine(x.Address));
Console.WriteLine();
Console.WriteLine("Service started...");
Console.ReadLine();
host.Close();
客户代码:
TestServiceClient client = new TestServiceClient();
client.ClientCredentials.UserName.UserName = "hej";//this is valid
client.ClientCredentials.UserName.Password = "hej";
System.Net.ServicePointManager.ServerCertificateValidationCallback =
((sender, certificate, chain, sslPolicyErrors) => true);
try
{
var result = client.GetData(123);
Console.WriteLine(result);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
Console.ReadLine();
答案 0 :(得分:1)
安全时间戳的目的是guard against "Replay Attacks"
在您的情况下,创建日期(在客户端上设置)在服务器上的日期之后将近12小时。最明显的解释是其中一个时钟设置不正确。
重播攻击检测can be disabled,其安全风险不会为requests have to be signed anyway to benefit from it。
关于证书,安装程序为documented on TechNet - 请注意,您可以查看证书是否已正确安装:
如果您要验证已安装证书,则可以加载 证书卡入,你应该在证书下看到它 - 当前用户信任的根证书颁发机构 - 证书。
一旦您的浏览器信任该证书,您的WCF客户端也将如此。