我正在尝试在WCF中添加SOAP安全头用户名令牌,对不起,我已经在上一篇文章中发布了我的所有路径,但得到了更多方法并在此处添加可能它可能有效。现在我得到一个例外
"无法拨打' WriteEndElement'而深度是' 0'。"
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);
}
}
}
如果我需要添加,等待专家的回复,请建议任何其他方案。