如果在我的服务端点上出现一般故障,则故障响应会被意外加密。
出于互操作性的原因,我创建了一个带有自定义绑定的端点,该框架设置了传输安全性,仅在soap 1.1上签名。
<service behaviorConfiguration="MyProject.WebServices.MyServiceBehavior"
name="MyProject.WebServices.Protected">
<endpoint address="" binding="customBinding" bindingConfiguration="mySoap11"
contract="MyProject.WebServices.IMyService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
<behavior name="MyProject.WebServices.MyServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceCredentials>
<clientCertificate>
<authentication revocationMode="NoCheck" trustedStoreLocation="LocalMachine"
certificateValidationMode="PeerOrChainTrust"/>
</clientCertificate>
<serviceCertificate findValue="aa bb cc dd ee ..."
storeLocation="LocalMachine"
storeName="My"
x509FindType="FindByThumbprint"/>
</serviceCredentials>
</behavior>
<customBinding>
<binding name="mySoap11">
<textMessageEncoding messageVersion="Soap11" />
<security allowSerializedSigningTokenOnReply="true" authenticationMode="MutualCertificate"
requireDerivedKeys="false" securityHeaderLayout="Lax" includeTimestamp="false"
messageProtectionOrder="EncryptBeforeSign" messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"
requireSecurityContextCancellation="false" requireSignatureConfirmation="false">
<localClientSettings detectReplays="false" />
<localServiceSettings detectReplays="false" />
<secureConversationBootstrap />
</security>
<httpTransport>
<extendedProtectionPolicy policyEnforcement="Never" />
</httpTransport>
</binding>
</customBinding>
有两个故障合约装饰操作合约。第一个用于一般故障,第二个是使用企业库的验证故障合同。服务契约属性和操作契约两个故障被修饰为
[ValidationBehavior()]
[ServiceContract(Namespace = "http://namespace", ProtectionLevel=ProtectionLevel.Sign)]
public interface IMyService
{
[OperationContract]
[FaultContract(typeof(ValidationFault), Namespace = "http://namespace", ProtectionLevel = ProtectionLevel.Sign)]
[FaultContract(typeof(MyFaultContract), Namespace = "http://namespace", ProtectionLevel = ProtectionLevel.Sign)]
MyTypeOfContractResponse Method(MyTypeOfContractRequest request);
}
//The message response contract
[MessageContract(IsWrapped = false)]
public class MyTypeOfContractResponse
{
[MessageBodyMember]
public bool Success { get; set; }
}
//The message request contract
[MessageContract(IsWrapped = true, ProtectionLevel=ProtectionLevel.Sign)]
[HasSelfValidation]
public class MyTypeOfContractRequest
{
[MessageBodyMember(Order = 0)]
public bool MyValue { get; set; }
[SelfValidation]
public void DoValidate(ValidationResults results)
{
...
}
}
等等……
如果发出了良好的请求,则响应正文是正常可读的签名和未加密的。如果发生验证错误或抛出 WCF 错误合同异常,则响应再次有效、可读且仅带有签名。
<s:Body u:Id="_1">
<Success xmlns="http://namespace">true</Success>
</s:Body>
但是,如果它以 throw new Exception() 的形式抛出一般错误;或引发错误;假设消息合同消息正文成员的顺序发生了变化;然后响应正文被加密,例如
<s:Body u:Id="_2">
<e:EncryptedData Id="_1" Type="http://www.w3.org/2001/04/xmlenc#Content" xmlns:e="http://www.w3.org/2001/04/xmlenc#">
<e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"></e:EncryptionMethod>
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<o:SecurityTokenReference xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<o:Reference URI="#_0"></o:Reference>
</o:SecurityTokenReference>
</KeyInfo>
<e:CipherData>
<e:CipherValue>+7Zs7rMkF...</e:CipherValue>
</e:CipherData>
</e:EncryptedData>
</s:Body>
您将如何防止未处理的响应被加密?