我正在为一个 Java Web 服务创建一个 WCF 客户端,该客户端不受我的控制,并且遇到了问题,因为如果对时间戳标头元素进行签名,该服务将返回 InvalidSecurity 错误。
我当前正在使用以下SecurityBindingElement
,但这会自动为Timestamp元素签名。我怎样才能阻止这种行为?更一般地说,我如何控制哪些元素已签名,哪些元素未签名?
var version = MessageSecurityVersion.WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10;
var sec = (AsymmetricSecurityBindingElement)SecurityBindingElement.CreateMutualCertificateBindingElement(version);
sec.EndpointSupportingTokenParameters.Signed.Add(new UserNameSecurityTokenParameters());
sec.MessageSecurityVersion = version;
sec.IncludeTimestamp = true;
sec.MessageProtectionOrder = MessageProtectionOrder.EncryptBeforeSign;
通常,您可以通过实现自定义endpoint行为来控制哪些元素获得签名,并且在AddBindingParameter()中执行如下操作:
ChannelProtectionRequirements requirements = bindingParameters.Find<ChannelProtectionRequirements>();
requirements.IncomingSignatureParts...
然而,我看不到在这个api中删除元素的方法——只是添加一些。也许你可以私下反思一下。
我也不确定这是否能保证安全。我认为您唯一的方法是将“includeTimestamp”设置为false,在这种情况下,您将不会向客户端发送时间戳。如果你必须发送一个时间戳(未签名),那么仍然保持它为假,并通过一个定制的编码器自己创建时间戳。应该不难。只要注意不要更改消息中的任何其他内容,如果消息已经签名的话。
标头中的每个元素都可以使用 [MessageHeader] 标记 - 您可以使用此元素设置保护级别。
我无法对答案进行投票,但克里斯的建议对我有效。我想阻止签署主体(从而期待签署回应主体)。我转到接口,并将ProtectionLevel=None添加到MessageContracts中MessageBody属性的每个实例。因为所有部分都不需要签名,WCF跳过对请求体的签名,也不希望对响应体进行签名。它仍然在我的头字段上签名。