WCF .NET调用带WS Security的Java Web服务的配置实现问题
配置调整方案
1. 修改绑定与客户端行为配置,输出X509IssuerSerial结构
修改你的WCF配置,调整安全节点的令牌引用样式为IssuerSerial,同时配置客户端证书:
<customBinding> <binding name="DigitalSignature"> <textMessageEncoding messageVersion="Soap12" /> <security defaultAlgorithmSuite="Basic128Rsa15" enableUnsecuredResponse="true" authenticationMode="MutualCertificate" includeTimestamp="false" messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"> <localClientSettings securityTokenReferenceStyle="IssuerSerial" includeTimestamp="false" /> </security> <!-- 配置HTTP Basic认证 --> <httpTransport authenticationScheme="Basic" /> </binding> </customBinding> <behaviors> <endpointBehaviors> <behavior name="ClientCertBehavior"> <clientCredentials> <!-- 配置客户端签名证书,替换为你实际的证书查询参数 --> <clientCertificate findValue="证书指纹" storeLocation="CurrentUser" storeName="My" x509FindType="FindByThumbprint" /> <!-- 不需要验证服务端证书的话可设置为None,生产环境建议按实际规则校验 --> <serviceCertificate> <authentication certificateValidationMode="None" /> </serviceCertificate> </clientCredentials> </behavior> </endpointBehaviors> </behaviors> <!-- 关联配置到服务端点 --> <endpoint address="你的Java服务地址" binding="customBinding" bindingConfiguration="DigitalSignature" contract="你生成的服务契约接口名" behaviorConfiguration="ClientCertBehavior" />
2. 配置Basic认证凭据
在初始化服务客户端时设置Basic认证的用户名密码:
var client = new YourServiceClient(); client.ClientCredentials.UserName.UserName = "你的Basic认证用户名"; client.ClientCredentials.UserName.Password = "你的Basic认证密码";
3. 自定义消息拦截器补全规范化命名空间配置
WCF默认不会生成InclusiveNamespaces节点,需要实现客户端消息拦截器修改请求报文:
using System; using System.IO; using System.Xml; using System.ServiceModel; using System.ServiceModel.Dispatcher; using System.ServiceModel.Description; using System.ServiceModel.Channels; public class WsSecurityMessageInspector : IClientMessageInspector { public void AfterReceiveReply(ref Message reply, object correlationState) { // 无响应处理需求可留空 } public object BeforeSendRequest(ref Message request, IClientChannel channel) { var buffer = request.CreateBufferedCopy(int.MaxValue); var xmlDoc = new XmlDocument(); using (var ms = new MemoryStream()) using (var writer = XmlWriter.Create(ms)) { buffer.CreateMessage().WriteMessage(writer); writer.Flush(); ms.Position = 0; xmlDoc.Load(ms); } var nsManager = new XmlNamespaceManager(xmlDoc.NameTable); nsManager.AddNamespace("ds", "http://www.w3.org/2000/09/xmldsig#"); nsManager.AddNamespace("wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"); // 移除默认生成的BinarySecurityToken节点(你的目标报文不需要该节点) var bstNode = xmlDoc.SelectSingleNode("//wsse:BinarySecurityToken", nsManager); bstNode?.ParentNode.RemoveChild(bstNode); // 给CanonicalizationMethod节点添加s u前缀的InclusiveNamespaces var rootCanonicalNode = xmlDoc.SelectSingleNode("//ds:SignedInfo/ds:CanonicalizationMethod", nsManager) as XmlElement; if (rootCanonicalNode != null) { var incNode = xmlDoc.CreateElement("ec", "InclusiveNamespaces", "http://www.w3.org/2001/10/xml-exc-c14n#"); incNode.SetAttribute("PrefixList", "s u"); rootCanonicalNode.AppendChild(incNode); } // 给Transform下的CanonicalizationMethod节点添加u前缀的InclusiveNamespaces var transformCanonicalNode = xmlDoc.SelectSingleNode("//ds:Transform/ds:CanonicalizationMethod", nsManager) as XmlElement; if (transformCanonicalNode != null) { var incNode = xmlDoc.CreateElement("ec", "InclusiveNamespaces", "http://www.w3.org/2001/10/xml-exc-c14n#"); incNode.SetAttribute("PrefixList", "u"); transformCanonicalNode.AppendChild(incNode); } // 重新生成请求消息 using (var ms = new MemoryStream()) using (var writer = XmlWriter.Create(ms)) { xmlDoc.WriteTo(writer); writer.Flush(); ms.Position = 0; var reader = XmlReader.Create(ms); request = Message.CreateMessage(reader, int.MaxValue, request.Version); } return null; } } // 注册拦截器的端点行为 public class WsSecurityEndpointBehavior : IEndpointBehavior { public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { } public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) { clientRuntime.MessageInspectors.Add(new WsSecurityMessageInspector()); } public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { } public void Validate(ServiceEndpoint endpoint) { } }
初始化客户端时注册该行为:
client.Endpoint.Behaviors.Add(new WsSecurityEndpointBehavior());
内容的提问来源于stack exchange,提问作者Jonathan Ayoub
相关产品推荐
相关产品推荐

