how to add SOAP Security header

前端 未结 3 845
猫巷女王i
猫巷女王i 2021-02-04 16:08

I\'ve read a lot of articles and answers but I couldn\'t work it out.

I\'m using .NET Framework 4.0 on my project. So, I first added the WebService as a Service Referenc

相关标签:
3条回答
  • 2021-02-04 16:29

    I have had the same issue as the First Attempt of the question and I needed to have a output same as the question. The answer is perfectly fine but Just to improve on the above answer or i should say combine the answer with the link i did the the following.

     public class Security : MessageHeader
    {
        private readonly string _password, _username, _nonce;
        private readonly DateTime _createdDate;
    
        public Security(string id, string username, string password, string nonce)
        {
            _password = password;
            _username = username;
            _nonce = nonce;
            _createdDate = DateTime.Now;
            this.Id = id;
        }
    
        public string Id { get; set; }
    
        public override string Name => "Security";
    
        public override string Namespace => "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)
        {
            writer.WriteStartElement("wsse", "UsernameToken", Namespace);
            writer.WriteAttributeString("Id", "UsernameToken-10");
            writer.WriteAttributeString("wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
    
            writer.WriteStartElement("wsse", "Username", Namespace);
            writer.WriteValue(_username);
            writer.WriteEndElement();
    
            writer.WriteStartElement("wsse", "Password", Namespace);
            writer.WriteAttributeString("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
            writer.WriteValue(_password);
            writer.WriteEndElement();
    
            writer.WriteStartElement("wsse", "Nonce", Namespace);
            writer.WriteAttributeString("EncodingType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");
            writer.WriteValue(_nonce);
            writer.WriteEndElement();
    
            writer.WriteStartElement("wsse", "Created", Namespace);
            writer.WriteValue(_createdDate.ToString("YYYY-MM-DDThh:mm:ss"));
            writer.WriteEndElement();
    
            writer.WriteEndElement();
        }
    }
    /// <summary>
    /// Represents a message inspector object that can be added to the <c>MessageInspectors</c> collection to view or modify messages.
    /// </summary>
    public class ClientMessageInspector : IClientMessageInspector
    {
        /// <summary>
        /// Enables inspection or modification of a message before a request message is sent to a service.
        /// </summary>
        /// <param name="request">The message to be sent to the service.</param>
        /// <param name="channel">The WCF client object channel.</param>
        /// <returns>
        /// The object that is returned as the <paramref name="correlationState " /> argument of
        /// the <see cref="M:System.ServiceModel.Dispatcher.IClientMessageInspector.AfterReceiveReply(System.ServiceModel.Channels.Message@,System.Object)" /> method.
        /// This is null if no correlation state is used.The best practice is to make this a <see cref="T:System.Guid" /> to ensure that no two
        /// <paramref name="correlationState" /> objects are the same.
        /// </returns>
        public object BeforeSendRequest(ref Message request, IClientChannel channel)
        {
    ///enter your username and password here.
            Security header = new Security("xx", "xx", "xx!","xx");
    
            request.Headers.Add(header);
            return header.Name;
        }
    
        /// <summary>
        /// Enables inspection or modification of a message after a reply message is received but prior to passing it back to the client application.
        /// </summary>
        /// <param name="reply">The message to be transformed into types and handed back to the client application.</param>
        /// <param name="correlationState">Correlation state data.</param>
        public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
        {
    
        }
    }
    
    /// <summary>
    /// Represents a run-time behavior extension for a client endpoint.
    /// </summary>
    public class CustomEndpointBehavior : IEndpointBehavior
    {
        /// <summary>
        /// Implements a modification or extension of the client across an endpoint.
        /// </summary>
        /// <param name="endpoint">The endpoint that is to be customized.</param>
        /// <param name="clientRuntime">The client runtime to be customized.</param>
        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
            clientRuntime.ClientMessageInspectors.Add(new ClientMessageInspector());
        }
    
        /// <summary>
        /// Implement to pass data at runtime to bindings to support custom behavior.
        /// </summary>
        /// <param name="endpoint">The endpoint to modify.</param>
        /// <param name="bindingParameters">The objects that binding elements require to support the behavior.</param>
        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {
            // Nothing special here
        }
    
        /// <summary>
        /// Implements a modification or extension of the service across an endpoint.
        /// </summary>
        /// <param name="endpoint">The endpoint that exposes the contract.</param>
        /// <param name="endpointDispatcher">The endpoint dispatcher to be modified or extended.</param>
        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {
            // Nothing special here
        }
    
        /// <summary>
        /// Implement to confirm that the endpoint meets some intended criteria.
        /// </summary>
        /// <param name="endpoint">The endpoint to validate.</param>
        public void Validate(ServiceEndpoint endpoint)
        {
            // Nothing special here
        }
    }
    
    0 讨论(0)
  • 2021-02-04 16:34

    I solved it by using WCF without any credentials declared. I did it by building my custom header I got help from this link

    public class SoapSecurityHeader : MessageHeader
        {
            private readonly string _password, _username, _nonce;
            private readonly DateTime _createdDate;
    
            public SoapSecurityHeader(string id, string username, string password, string nonce)
            {
                _password = password;
                _username = username;
                _nonce = nonce;
                _createdDate = DateTime.Now;
                this.Id = id;
            }
    
            public string Id { get; set; }
    
            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)
            {
                writer.WriteStartElement("wsse", "UsernameToken", Namespace);
                writer.WriteAttributeString("Id", "UsernameToken-10");
                writer.WriteAttributeString("wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
    
                writer.WriteStartElement("wsse", "Username", Namespace);
                writer.WriteValue(_username);
                writer.WriteEndElement();
    
                writer.WriteStartElement("wsse", "Password", Namespace);
                writer.WriteAttributeString("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
                writer.WriteValue(_password);
                writer.WriteEndElement();
    
                writer.WriteStartElement("wsse", "Nonce", Namespace);
                writer.WriteAttributeString("EncodingType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");
                writer.WriteValue(_nonce);
                writer.WriteEndElement();
    
                writer.WriteStartElement("wsse", "Created", Namespace);
                writer.WriteValue(_createdDate.ToString("YYYY-MM-DDThh:mm:ss"));
                writer.WriteEndElement();
    
                writer.WriteEndElement();
            }
        }
    

    and to how to use the header I got it from this link.

    0 讨论(0)
  • 2021-02-04 16:36

    Excelent post. All of you save my life!! I had to make some changes to get the following headers:

    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xml:mustUnderstand="1">
        <wsse:UsernameToken wsu:Id="UsernameToken-15" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
            <wsse:Username>EFO140714JPA</wsse:Username>
            <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">SgBJAHMANwBBACYANQBOAG8ANwAzACEANgBrAGEAJgBIAGwAJABMAA==</wsse:Password>
            <wsse:Nonce>SgBJAHMANwBBACYANQBOAG8ANwAzACEANgBrAGEAJgBIAGwAJABMAA==</wsse:Nonce>
            <wsu:Created>2016-08-04T11:24:10.0Z</wsu:Created>
        </wsse:UsernameToken>
    </wsse:Security>
    

    Tha changes I made are the following:

            public class SoapSecurityHeader : MessageHeader
            {
                private readonly string _password, _username, _nonce, _createdDate;
    
                public SoapSecurityHeader(string id, string username, string password, string nonce, string created)
                {
                    _password = password;
                    _username = username;
                    _nonce = nonce;
                    _createdDate = created;
                    this.Id = id;
                }
    
                public string Id { get; set; }
    
                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);
     ------->       writer.WriteXmlAttribute("mustUnderstand", "1");
                }
    
    
                protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
                {
                    writer.WriteStartElement("wsse", "UsernameToken", Namespace);
                    writer.WriteAttributeString("wsu:Id", "UsernameToken-15");
                    writer.WriteAttributeString("xmlns:wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
    
                    writer.WriteStartElement("wsse", "Username", Namespace);
                    writer.WriteValue(_username);
                    writer.WriteEndElement();
    
                    writer.WriteStartElement("wsse", "Password", Namespace);
      ----->        writer.WriteAttributeString("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest");
                    writer.WriteValue(_password);
                    writer.WriteEndElement();
    
                    writer.WriteStartElement("wsse", "Nonce", Namespace);
                    writer.WriteValue(_nonce);
                    writer.WriteEndElement();
    
      ------>       writer.WriteStartElement("wsu:Created");
                    writer.WriteValue(_createdDate);
                    writer.WriteEndElement();
    
                    writer.WriteEndElement();
                }
            }
    
    0 讨论(0)
提交回复
热议问题