我可以使用WCF方法在SOAP标头中添加此自定义WCF安全节点吗?

时间:2018-06-21 16:21:02

标签: vb.net wcf security soap header

我需要使用一个wsse:Security节点将这个SOAP流量发送到远程服务,该节点应该看起来像这样:

<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
                xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
    <wsse:UsernameToken wsu:Id="UsernameToken-5FJPET4ATPQZMREXU8C51DK9P6OTW022">
        <wsse:Username>NotQuiteThatStupid</wsse:Username>
        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">DonTBotherReadingThisNode</wsse:Password>
    </wsse:UsernameToken>
</wsse:Security>

我已经尝试使用WCF来完成此任务,因为它看起来像当前的标准,并且文档齐全。长话短说,我找不到使它起作用的方法。

我发挥了作用,从http://blog.aggregatedintelligence.com/2010/06/wcf-transportwithmessagecredential-and.html中汲取了灵感,并将XML节点直接写入标头中:

Dim z_bieTextBinding As TextMessageEncodingBindingElement = New TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8)
Dim z_bieHttpBinding As HttpTransportBindingElement = New HttpTransportBindingElement()
    Dim z_cbiBinding As CustomBinding = New CustomBinding(z_bieTextBinding, z_bieHttpBinding)

Dim z_epaFinalAddress As EndpointAddress = New EndpointAddress("http://some.where.over/the/rainbow")

Dim z_chfChannels As ChannelFactory(Of IRequestChannel) = New ChannelFactory(Of IRequestChannel)(z_cbiBinding, z_epaFinalAddress)
Dim z_rqcChannel As IRequestChannel = z_chfChannels.CreateChannel()

z_rqcChannel.Open()
Dim z_msgToSend As Message = Message.CreateMessage(MessageVersion.Soap11, p_strActionName, p_objMessageBody)
Dim z_strUserHeader As String = "<wsse:UsernameToken " & _
            "xmlns:wsse=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"" " & _
            "xmlns:wsu=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"" " & _
            "wsu:Id=""UsernameToken-5FJPET4ATPQZMREXU8C51DK9P6OTW022"">" & _
            "<wsse:Username>NoOneYaKnowPardner</wsse:Username>" & _
            "<wsse:Password Type=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText"">DonTBotherPal</wsse:Password>" & _
            "</wsse:UsernameToken>"
Dim z_xdoDocUserHeader As XmlDocument = New XmlDocument()
z_xdoDocUserHeader.LoadXml(z_strUserHeader)
Dim z_mheSecurityHeader As MessageHeader = MessageHeader.CreateHeader("Security", _
                                "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", _
                                z_xdoDocUserHeader.DocumentElement)
z_msgToSend.Headers.Add(z_mheSecurityHeader)

它确实起作用。 (xmlns属性与模型有些不同,但是它们仍然可以通过。)尽管如此,我仍然不能摆脱不依靠XML操作就应该可行的感觉。因此:

  1. 我是否认为这是“肮脏”的解决方案?
  2. 是否存在仅使用WCF对象,属性和方法的替代方法?

编辑:我尝试了另一种方法。我这样在Web.config中设置了绑定和端点:

<system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="bndSimpleGeneric"
                        messageEncoding="Text"/>
        </basicHttpBinding>
    </bindings>
    <client>
        <endpoint name="enpBasicEndpoint"
                    address="http://dms-uat.athoris.net/Athoris"
                    binding="basicHttpBinding"
                    bindingConfiguration="bndSimpleGeneric"
                    contract="System.ServiceModel.Channels.IRequestChannel">
            <headers>
                <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
                                xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
                    <wsse:UsernameToken>
                        <wsse:Username>CanTRememberWho</wsse:Username>
                        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">SomethingSomethingOrangesSomething</wsse:Password>
                    </wsse:UsernameToken>
                </wsse:Security>
            </headers>
        </endpoint>
    </client>
</system.serviceModel>

让我有更简单的代码:

    Dim z_chfChannels As New ChannelFactory(Of IRequestChannel)("enpBasicEndpoint")

    Dim z_rqcChannel As IRequestChannel = z_chfChannels.CreateChannel()

    z_rqcChannel.Open()

    Dim z_msgToSend As Message = Message.CreateMessage(MessageVersion.Soap11, "Action Name", "<MessageBody>Words</MessageBody>")
    Dim z_mbuToSend As MessageBuffer = z_msgToSend.CreateBufferedCopy(Integer.MaxValue)
    Dim z_msgResponse As Message = z_rqcChannel.Request(z_mbuToSend.CreateMessage())

    z_rqcChannel.Close()
    z_chfChannels.Close()

    Return z_msgResponse

如下面的注释所示,我不确定我是否应该对此感到满意,因为用户名(更糟糕的是密码)在Web.config中。不过,对我来说,它看起来比将XML代码与字符串组合在一起要好得多。和以前一样,欢迎对此事发表意见。

0 个答案:

没有答案