Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在WCF中向soap消息添加安全标头,_C#_Wcf_Soap - Fatal编程技术网

C# 如何在WCF中向soap消息添加安全标头,

C# 如何在WCF中向soap消息添加安全标头,,c#,wcf,soap,C#,Wcf,Soap,我正在尝试在WCF中添加SOAP安全头用户名令牌,很抱歉,我在上一篇文章中发布了我的所有跟踪信息,但得到了一些更多的方法,并在这里添加了可能会起作用的方法。现在我得到了一个例外 “深度为“0”时无法调用'WriteEndElement'。” 如果需要添加,请建议任何其他场景,等待专家的回复。在OnWriteHeaderContent中,您已经注释掉了一些WriteStarteElement调用,但没有注释掉它们对应的WriteEndElement调用-如果我计算正确,方法末尾有两个不必要的wri

我正在尝试在WCF中添加SOAP安全头用户名令牌,很抱歉,我在上一篇文章中发布了我的所有跟踪信息,但得到了一些更多的方法,并在这里添加了可能会起作用的方法。现在我得到了一个例外

“深度为“0”时无法调用'WriteEndElement'。”


如果需要添加,请建议任何其他场景,等待专家的回复。

在OnWriteHeaderContent中,您已经注释掉了一些WriteStarteElement调用,但没有注释掉它们对应的WriteEndElement调用-如果我计算正确,方法末尾有两个不必要的writer.WriteEndElement调用。@nodots:感谢您的回复,但在调试时我仍然可以看到header部分正在成帧,但在运行时没有添加header。下面是发送SOAP请求时的xml请求。>0@nodots:对此有什么想法/建议吗?在OnWriteHeaderContents中,您已经注释掉了一些WriteStarteElement调用,但没有注释掉它们对应的WriteEndElement调用-如果我计算正确,在方法末尾有两个不必要的writer.WriteEndElement调用。@nodots:谢谢您的回复,但在调试期间,我仍然可以看到header部分正在帧化,但在运行时没有添加任何header。下面是发送SOAP请求时的xml请求。>0@nodots:对此有什么想法/建议吗?在OnWriteHeaderContents中,您已经注释掉了一些WriteStarteElement调用,但没有注释掉它们对应的WriteEndElement调用-如果我计算正确,在方法末尾有两个不必要的writer.WriteEndElement调用。@nodots:谢谢您的回复,但在调试期间,我仍然可以看到header部分正在帧化,但在运行时没有添加任何header。下面是发送SOAP请求时的xml请求。>0@nodots:对此有什么想法/建议吗?
   using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Security.Cryptography;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Web;
using System.Text;
using System.Xml;
using Microsoft.Web.Services3.Design;
using Microsoft.Web.Services3;
//using CustomAssertion.ServiceReference1;

namespace test
{

    public class InspectorBehavior : IEndpointBehavior
    {
        public ClientInspector ClientInspector { get; set; }
        public InspectorBehavior(ClientInspector clientInspector)
        {
            ClientInspector = clientInspector;
        }
        public void Validate(ServiceEndpoint endpoint)
        { }
        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {
        }
        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        { }
        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
            if (this.ClientInspector == null) throw new InvalidOperationException("Caller must supply ClientInspector.");
            clientRuntime.MessageInspectors.Add(ClientInspector);
        }
    }

    public class ClientInspector : IClientMessageInspector
    {
        public MessageHeader[] Headers { get; set; }
        public ClientInspector(params MessageHeader[] headers)
        {
            Headers = headers;
        }
        public object BeforeSendRequest(ref Message request, IClientChannel channel)
        {
            if (Headers != null)
            {
                for (int i = Headers.Length - 1; i >= 0; i--)
                    request.Headers.Insert(0, Headers[i]);
            }
            return request;
        }
        public void AfterReceiveReply(ref Message reply, object correlationState)
        {
        }
    }

    public class SecurityHeader : MessageHeader
    {
        public string SystemUser { get; set; }
        public string SystemPassword { get; set; }
        public SecurityHeader(string systemUser, string systemPassword)
        {
            SystemUser = systemUser;
            SystemPassword = systemPassword;
        }
        public override string Name
        {
            get { return "Security"; }
        }
        public override string Namespace
        {
            get { return "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"; }
        }
        protected override void OnWriteStartHeader(XmlDictionaryWriter writer, MessageVersion messageVersion)
        {
            writer.WriteStartElement("wsse", Name, Namespace);
            writer.WriteXmlnsAttribute("wsse", Namespace);
        }
        protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
        {
            var nonce = new byte[64];
            RandomNumberGenerator.Create().GetBytes(nonce);
            string created = DateTime.Now.ToString("yyyy-MM-ddThh:mm:ss.msZ");
            writer.WriteStartElement("wsse", "UsernameToken", Namespace);
            writer.WriteXmlnsAttribute("wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
            writer.WriteValue(SystemUser);
            //writer.WriteStartElement("wsse", "Username", null);
            //writer.WriteString(SystemUser);
            writer.WriteEndElement();//End Username 

            writer.WriteStartElement("wsse", "Password", Namespace);
            //writer.WriteStartElement("wsse", "Password", null);
            writer.WriteAttributeString("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest");
            writer.WriteValue(ComputePasswordDigest(SystemPassword, nonce, created));
            //writer.WriteString(ComputePasswordDigest(SystemPassword, nonce, created));
            writer.WriteEndElement();//End Password 

            writer.WriteStartElement("wsse", "Nonce", null);
            writer.WriteAttributeString("EncodingType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");
            writer.WriteBase64(nonce, 0, nonce.Length);
            writer.WriteEndElement();//End Nonce 

            // writer.WriteStartElement("wsse", "Created", null);
            // writer.WriteString(created);
            // writer.WriteEndElement();//End Created 
            // writer.WriteEndElement();//End UsernameToken

            writer.Flush();
        }
        private string ComputePasswordDigest(string secret, byte[] nonceInBytes, string created)
        {
            byte[] createdInBytes = Encoding.UTF8.GetBytes(created);
            byte[] secretInBytes = Encoding.UTF8.GetBytes(secret);
            byte[] concatenation = new byte[nonceInBytes.Length + createdInBytes.Length + secretInBytes.Length];
            Array.Copy(nonceInBytes, concatenation, nonceInBytes.Length);
            Array.Copy(createdInBytes, 0, concatenation, nonceInBytes.Length, createdInBytes.Length);
            Array.Copy(secretInBytes, 0, concatenation, (nonceInBytes.Length + createdInBytes.Length), secretInBytes.Length);
            return Convert.ToBase64String(SHA1.Create().ComputeHash(concatenation));
        }
    }
    public class Service1 : IService1
    {

        public string security(int a)
        {
            ServiceReference1.Service1Client action = new ServiceReference1.Service1Client();
            action.Endpoint.Behaviors.Add(new InspectorBehavior(
            new ClientInspector(new SecurityHeader("username", "password"))));
            return action.GetData(8);
        }

    }
}