首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >带有SOAP级别身份验证和HTTP身份验证的Onvif SOAP请求

带有SOAP级别身份验证和HTTP身份验证的Onvif SOAP请求
EN

Stack Overflow用户
提问于 2014-01-16 18:57:43
回答 2查看 4K关注 0票数 1

这个问题在这里已经讨论过几个话题,但我找不到答案。

我想做的是通过Onvif接口使用IP摄像头。我从Onvif主页中的WSDL文件中生成了web服务,并按照建议的这里添加了自定义SOAP身份验证代码,并且能够检索设备功能等等。

但是对于某些服务,例如PTZ控件,也需要HTTP身份验证。我的代码删除了ClientCredentials行为(因此,我想设置它们没有任何意义,但我仍然保留了这些行,希望HTTPTransport会尝试使用它们):

代码语言:javascript
运行
复制
HttpTransportBindingElement httpBindingElement = new HttpTransportBindingElement();
httpBindingElement.AuthenticationScheme = AuthenticationSchemes.Basic;
...
PTZClient ptzClient = new PTZClient(customBinding, endPointAddress);
ptzClient.Endpoint.Behaviors.Remove(typeof(System.ServiceModel.Description.ClientCredentials));
UsernameClientCredentials onvifCredentials = new UsernameClientCredentials(new UsernameInfo(_username, _password));
ptzClient.Endpoint.Behaviors.Add(onvifCredentials);
ptzClient.ClientCredentials.UserName.UserName = _username;
ptzClient.ClientCredentials.UserName.Password = _password;

不过,当我查看wireshark时,我仍然看到SOAP身份验证是生成的,但是没有设置HTTP身份验证头(嗯,我已经预料到了,因为这里有一个自定义的行为)。因此,问题是,如果我以这种方式创建绑定,我添加HTTP身份验证头的最佳选项是什么?我可以添加一个消息检查器吗?如果是的话,可以添加任何示例吗?必须创建不同的传输绑定吗?我见过有人建议其他人使用BasicHttpBinding,然后在此基础上设置Security属性,但是在这种情况下凭据到哪里去了,以及如何将BasicHttpBinding实例应用到绑定中?WCF中是否有由HTTP 401代码触发的回调,我可以将其连接起来,然后提供报头?这实际上是我对WCF的第一次体验,到目前为止,我已经做了所有的工作,从互联网上找到的例子,但关于这个特定的问题,我还没有找到任何东西。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-02-28 13:18:13

如果有人感兴趣的话,我就是这么做的。我以以下方式将BasicHttpBinding与客户端凭据组合在一起:

代码语言:javascript
运行
复制
TransportSecurityBindingElement transportSecurity = new TransportSecurityBindingElement();
// UsernameCredentials is a class implementing WS-UsernameToken authentication
transportSecurity.EndpointSupportingTokenParameters.SignedEncrypted.Add(new UsernameTokenParameters());
transportSecurity.AllowInsecureTransport = true;
transportSecurity.IncludeTimestamp = false;
TextMessageEncodingBindingElement messageEncoding = new TextMessageEncodingBindingElement(MessageVersion.Soap12, Encoding.UTF8);
HttpClientCredentialType[] credentialTypes = new HttpClientCredentialType[3] { HttpClientCredentialType.None, HttpClientCredentialType.Basic, HttpClientCredentialType.Digest };
...
foreach (HttpClientCredentialType credentialType in credentialTypes)
{
    BasicHttpBinding httpBinding = new BasicHttpBinding(BasicHttpSecurityMode.TransportCredentialOnly);
    httpBinding.Security.Transport.ClientCredentialType = credentialType;
    BindingElementCollection elements = new BindingElementCollection(new BindingElement[1]{messageEncoding});
    foreach(BindingElement element in httpBinding.CreateBindingElements())
    {
        if (element is TextMessageEncodingBindingElement)
            continue;
        elements.Add(element);
    }
    CustomBinding customBinding = new CustomBinding(elements);
    DeviceClient deviceClient = new DeviceClient(customBinding, endPointAddress);
    if (credentialType == HttpClientCredentialType.Basic)
    {
         // Set all credentials, not sure from which one WCF actually takes the value
         deviceClient.ClientCredentials.UserName.UserName = pair[0];
         deviceClient.ClientCredentials.UserName.Password = pair[1];
    }
    else if (credentialType == HttpClientCredentialType.Digest)
    {
        deviceClient.ClientCredentials.HttpDigest.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Delegation;
        deviceClient.ClientCredentials.HttpDigest.ClientCredential.UserName = pair[0];
        deviceClient.ClientCredentials.HttpDigest.ClientCredential.Password = pair[1];
    }
}

这在我们不知道身份验证模式的设备上有效地工作,并且在两个(HTTP/SOAP)身份验证级别上都能工作。

票数 3
EN

Stack Overflow用户

发布于 2014-02-28 07:36:13

我详细介绍了HTTP摘要在另一个回答中是如何工作的。

请记住,根据PRE_AUTH的5.12.1节,只有类岩心规格的函数需要身份验证。

您应该调用除PRE_AUTH之外的任何类的函数,而不需要任何形式的身份验证。如果您得到一个HTTP 401,那么您必须使用HTTP,否则您将不得不使用with。

您不能直接使用HTTP摘要,因为您至少需要该设备向您发送HTTP摘要的质询。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21170475

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档