我正在尝试使用自定义绑定使用通过 UsernameToken 传入 SOAP 标头的身份验证 Web 服务
ICollection<BindingElement> bindingElements = new List<BindingElement>();
HttpsTransportBindingElement httpBindingElement = new HttpsTransportBindingElement();
CustomTextMessageBindingElement textBindingElement = new CustomTextMessageBindingElement();
SecurityBindingElement securityElement = SecurityBindingElement.CreateUserNameOverTransportBindingElement();
securityElement.IncludeTimestamp = false;
bindingElements.Add(securityElement);
bindingElements.Add(textBindingElement);
bindingElements.Add(httpBindingElement);
CustomBinding binding = new CustomBinding(bindingElements);
EndpointAddress address = new EndpointAddress("https://....");
var client = new WebServiceClient(binding, address);
client.ClientCredentials.UserName.UserName = "USERNAME HERE";
client.ClientCredentials.UserName.Password = "PASSWORD HERE";
using (new OperationContextScope(client.InnerChannel))
{
var req = new WebServiceRequest();
var resp = client.initiate(req);
}
得到一个例外:
消息安全验证失败。
无法使用 BinarySecretSecurityToken 的“ http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd ”命名空间从“BinarySecurityToken”元素中读取令牌,其中'oblix:ObSSOCookie' 值类型。如果此元素预计有效,请确保将安全性配置为使用指定名称、命名空间和值类型的令牌。"}
服务器堆栈跟踪:
在 System.ServiceModel.Security.TransportSecurityProtocol.VerifyIncomingMessage(消息和消息,TimeSpan 超时)在 System.ServiceModel.Security.SecurityProtocol.VerifyIncomingMessage(消息和消息,TimeSpan 超时,SecurityProtocolCorrelationState[] 相关状态)在 System.ServiceModel.Channels.SecurityChannelFactory
1.SecurityRequestChannel.ProcessReply(Message reply, SecurityProtocolCorrelationState correlationState, TimeSpan timeout) at System.ServiceModel.Channels.SecurityChannelFactory
1.SecurityRequestChannel.Request(Message message, TimeSpan timeout) at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object [] ins, Object[] outs, TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation) at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
这是提琴手捕获的响应:
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="oblix:ObSSOCookie" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:oblix="http://schemas.oblix.com/ws/2004/04/authentication"><!--REMOVED--></wsse:BinarySecurityToken>
</wsse:Security>
</env:Header>
<env:Body>
<MobileAppsLoginSSOProcessResponse xmlns="http://xmlns.oracle.com/MobileAppsLoginSSO">
<ReturnStatus>SUCCESS</ReturnStatus>
</MobileAppsLoginSSOProcessResponse>
</env:Body>
</env:Envelope>
我正在使用http://msdn.microsoft.com/en-us/library/ms751486%28v=vs.100%29.aspx之后的 CustomTextMessageEncoder
编辑:
正如 Yaron 所建议的,除非我从响应中删除 BinarySecurityToken 标记,否则代码将失败并出现上述消息安全验证失败异常。
响应中的“oblix:ObSSOCookie”是服务在成功身份验证后发送回客户端的身份验证 cookie,我相信客户端需要保存此 cookie。
解决方案:
按照 Yaron 在最终编辑中的建议,我SecurityElementBinding
从自定义绑定中删除并使用自定义消息检查器 ( IClientMessageInspector
) 将安全标记注入标头。
这允许仅解释来自 SOAP 主体的响应,并且我可以在AfterReceiveReply
我的IClientMessageInspector
实现中读取 SOAP 响应标头。