【发布时间】:2013-08-16 12:12:08
【问题描述】:
我正在尝试使用通过自定义绑定传入带有 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);
}
遇到异常:
邮件安全验证失败。
无法从 'BinarySecurityToken' 元素中读取令牌 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' BinarySecretSecurityToken 的命名空间,带有“oblix:ObSSOCookie” 值类型。如果预计此元素有效,请确保 security 配置为使用具有名称、命名空间和 指定的值类型。"}
服务器堆栈跟踪:
在 System.ServiceModel.Security.TransportSecurityProtocol.VerifyIncomingMessage(Message& 消息,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.SecurityChannelFactory1.SecurityRequestChannel.Request(消息 消息,TimeSpan 超时)在 System.ServiceModel.Dispatcher.RequestChannelBinder.Request(消息 消息,TimeSpan 超时)在 System.ServiceModel.Channels.ServiceChannel.Call(字符串动作, Boolean oneway, ProxyOperationRuntime 操作, Object[] ins, Object[] 出局,TimeSpan 超时)在 System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall,ProxyOperationRuntime 操作)在 System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage 留言)
fiddler 捕捉到的响应如下:
<?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 主体的响应,并且我可以在我的 IClientMessageInspector 实现的 AfterReceiveReply 中读取 SOAP 响应标头。
【问题讨论】: