1

我正在尝试使用自定义绑定使用通过 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.SecurityChannelFactory1.SecurityRequestChannel.ProcessReply(Message reply, SecurityProtocolCorrelationState correlationState, TimeSpan timeout) at System.ServiceModel.Channels.SecurityChannelFactory1.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 响应标头。

4

1 回答 1

1

服务器在响应中返回一个 x.509 令牌,WCF 不确定如何处理它(用户名身份验证中不应出现此令牌)。我看到两个选项:

  1. 在您的编码器中从响应中删除安全标签

    或者

  2. 根本不使用安全性,并且在编码器(或消息检查器,如果您愿意)将用户/传递标头推送到请求

编辑:你说这个令牌应该由客户端在进一步的调用中使用。我不确定处理这个问题的正确方法是什么,所以我会给出一个可行的快速方法(但感觉有点不完整)。根本不定义任何安全性(从绑定中删除安全元素)。然后使用自定义消息检查器(或编码器,但更难)以正确的格式推送用户/传递的消息(查看使用安全绑定时它们是如何发送的)。这应该不难。那么 WCF 将不会在响应时验证令牌。您可以使用已有的消息检查器来检查响应并提取令牌。您的主类(初始化代理)也是初始化检查器的类,因此它应该有权访问其数据成员以访问令牌并重新发送它。

如果服务器将令牌发送到正文而不是标题中,那就容易多了。也可能有一种方法可以通过实现自定义标记/行为以非修补方式做到这一点,但在我看来,这增加了更多抽象,最好是具体的。

于 2013-08-16T12:45:59.240 回答