我正在使用此博客来实现nonce,密码文本。 http://benpowell.org/supporting-the-ws-i-basic-profile-password-digest-in-a-wcf-client-proxy/ 我见过许多其他博客,但我想尝试一下。
这是我到目前为止所做的 我先说,我无法控制服务。我只是消费者。
passwordtextmessaginspector实现IClientMessageInspector,它允许我们修改传出消息。在这种情况下,我想在包含nonce的消息中添加usernametoken。所以Ben在BeforeRequestSent中使用了WSE。 使用System;
public class PasswordTextMessageInspector : IClientMessageInspector
{
public string Username { get; set; }
public string Password { get; set; }
public PasswordTextMessageInspector(string username, string password)
{
this.Username = username;
this.Password = password;
}
#region IClientMessageInspector Members
public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
{
throw new NotImplementedException();
}
public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
{
// Use the WSE 3.0 security token class
UsernameToken token = new UsernameToken(this.Username, this.Password, PasswordOption.SendPlainText);
// Serialize the token to XML
XmlElement securityToken = token.GetXml(new XmlDocument());
//
MessageHeader securityHeader = MessageHeader.CreateHeader("Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", securityToken, false);
request.Headers.Add(securityHeader);
// complete
return Convert.DBNull;
}
这是自定义行为
public class PasswordTextBehavior : IEndpointBehavior
{
public string Username { get; set; }
public string Password { get; set; }
public PasswordTextBehavior(string username, string password)
{
this.Username = username;
this.Password = password;
}
#region IEndpointBehavior Members
public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{
throw new NotImplementedException();
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
{
clientRuntime.MessageInspectors.Add(new PasswordTextMessageInspector(this.Username, this.Password));
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
{
throw new NotImplementedException();
}
public void Validate(ServiceEndpoint endpoint)
{
throw new NotImplementedException();
}
#endregion
}
}
我的肥皂请求已经有2 x509证书。我只是在发送之前用nonce添加这个usernametoken。 这就是我的proxyclient的样子
private ProxyGeneration.MHSClient GetProxy()
{
ProxyGeneration.MHSClient proxy = new ProxyGeneration.MHSClient(GetCustomBinding(), new EndpointAddress(new Uri("https://service100.emedny.org:9047/MHService"), EndpointIdentity.CreateDnsIdentity("SEREVR"), new AddressHeaderCollection()));
var vs = proxy.Endpoint.Behaviors.Where((i) => i.GetType().Namespace.Contains("VisualStudio"));
proxy.Endpoint.Behaviors.Remove((System.ServiceModel.Description.IEndpointBehavior)vs.Single());
proxy.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindBySubjectName,"USER");
proxy.ClientCredentials.ServiceCertificate.SetDefaultCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindBySubjectName, "SERVER");
PasswordTextBehavior behavior = new PasswordTextBehavior("USER", "PWD");
proxy.Endpoint.Behaviors.Add(behavior);
proxy.ClientCredentials.UserName.UserName = "USER";
proxy.ClientCredentials.UserName.Password = "PWD";
return proxy;
}
private CustomBinding GetCustomBinding()
{
AsymmetricSecurityBindingElement secBE = (AsymmetricSecurityBindingElement)SecurityBindingElement.CreateMutualCertificateBindingElement
(
MessageSecurityVersion.WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10
);
secBE.ProtectTokens = false;
X509SecurityTokenParameters x509ProtectionParameters = new X509SecurityTokenParameters();
x509ProtectionParameters.RequireDerivedKeys = false;
x509ProtectionParameters.X509ReferenceStyle = X509KeyIdentifierClauseType.SubjectKeyIdentifier;
x509ProtectionParameters.ReferenceStyle = SecurityTokenReferenceStyle.Internal;
//x509ProtectionParameters.InclusionMode = SecurityTokenInclusionMode.AlwaysToRecipient;
secBE.MessageSecurityVersion = System.ServiceModel.MessageSecurityVersion.WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12;
secBE.InitiatorTokenParameters = x509ProtectionParameters;
secBE.RecipientTokenParameters = x509ProtectionParameters;
secBE.MessageProtectionOrder = System.ServiceModel.Security.MessageProtectionOrder.SignBeforeEncrypt;
secBE.SecurityHeaderLayout = SecurityHeaderLayout.Strict;
secBE.EnableUnsecuredResponse = true;
secBE.SetKeyDerivation(false);
secBE.DefaultAlgorithmSuite = System.ServiceModel.Security.SecurityAlgorithmSuite.TripleDesRsa15;
secBE.EndpointSupportingTokenParameters.Signed.Add(new UserNameSecurityTokenParameters());
secBE.ProtectTokens = true;
// secBE.in = SecurityTokenInclusionMode.Never, RequireDerivedKeys = false );
secBE.EnableUnsecuredResponse = true;
secBE.IncludeTimestamp = false;
TextMessageEncodingBindingElement textEncBE = new TextMessageEncodingBindingElement(MessageVersion.Soap11WSAddressing10, System.Text.Encoding.UTF8);
HttpsTransportBindingElement httpsBE = new HttpsTransportBindingElement();
httpsBE.RequireClientCertificate = true;
CustomBinding myBinding = new CustomBinding();
myBinding.Elements.Add(secBE);
myBinding.Elements.Add(textEncBE);
myBinding.Elements.Add(httpsBE);
return myBinding;
}
所以我添加了一个新的Behavior PasswordTextBehavior proxy.endpoint.behavior.add(passwordtextbehavior)。
这是一种有效的方法吗?我有两个安全部分。
我的标题
<Security xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken wsu:Id="SecurityToken-ec50def9-1c3b-476a-9bcc-2af556e5e0e7" 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:Username><!--Removed--></wsse:Username><wsse:Password><!--Removed-->
</wsse:Password><wsse:Nonce><!--Removed--></wsse:Nonce><wsu:Created>2013-05-28T14:56:46Z</wsu:Created></wsse:UsernameToken>
</Security>
<a:To s:mustUnderstand="1" u:Id="_6">https://service100.emedny.org:9047/MHService</a:To>
<o:Security s:mustUnderstand="1"
xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<o:BinarySecurityToken><!--Removed--></o:BinarySecurityToken>
<o:BinarySecurityToken><!--Removed--></o:BinarySecurityToken>
<e:EncryptedKey Id="_0" xmlns:e="http://www.w3.org/2001/04/xmlenc#">
应该只有一个安全标签,一个必须理解。
供应商样本
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:mhs="http://org/TEST/mhs/" xmlns:urn="urn:hl7-org:v3">
<soapenv:Header>
<wsse:Security soap:mustUnderstand="1" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:BinarySecurityToken ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="SecurityToken-e00c8062-83d2-4f04-88fc-996218e7bb3d">MIICeDCC....(signed user MLS cert).......</wsse:BinarySecurityToken>
<wsse:BinarySecurityToken ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="SecurityToken-c0cc2cd4-cb77-4fa5-abfa-bd485afd1685">MIIDFj.....( MLS web-service end-point public cert)........</wsse:BinarySecurityToken>
<wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="SecurityToken-970e9a80-00cc-4c86-8ec4-3ba16e029a5b">
<wsse:Username>....your_username.....</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">.....your_plaintext_password....</wsse:Password>
<wsse:Nonce>KNyu6MsXCkTg4DDyvwvEiw==</wsse:Nonce>
<wsu:Created>2010-09-15T18:00:30Z</wsu:Created>
</wsse:UsernameToken>
<xenc:EncryptedKey xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<wsse:SecurityTokenReference>
<wsse:Reference URI="#SecurityToken-c0cc2cd4-cb77-4fa5-abfa-bd485afd1685" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/>
</wsse:SecurityTokenReference>
</KeyInfo>
<xenc:CipherData>
<xenc:CipherValue>gpBAWt91pdwhKva............</xenc:CipherValue>
</xenc:CipherData>
<xenc:ReferenceList>
<xenc:DataReference URI="#Enc-0641b860-b16d-4941-91c0-d60bece67794"/>
</xenc:ReferenceList>
</xenc:EncryptedKey>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference URI="#Id-f10674fd-b999-47c9-9568-c11fa5e5405b">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>wRUq.........</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>tBSsaZi........</SignatureValue>
<KeyInfo>
<wsse:SecurityTokenReference>
<wsse:Reference URI="#SecurityToken-e00c8062-83d2-4f04-88fc-996218e7bb3d" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/>
</wsse:SecurityTokenReference>
</KeyInfo>
</Signature>
</wsse:Security>
</soapenv:Header>
<soapenv:Body wsu:Id="Id-f10674fd-b999-47c9-9568-c11fa5e5405b" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<xenc:EncryptedData Id="Enc-0641b860-b16d-4941-91c0-d60bece67794" Type="http://www.w3.org/2001/04/xmlenc#Content" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/>
<xenc:CipherData>
<xenc:CipherValue>SQsTCAK6ZaVhojB8+Y.........</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedData>
</soapenv:Body>
</soapenv:Envelope>
答案 0 :(得分:0)
你显然已经启动并运行了WCF,这是跟踪这类问题的bext方法。
您现在需要一个预期消息输出的示例。从那以后,你可以开始有条不紊地向后工作。
您需要使用证书建立签名。如果您愿意,可以使用WSE classes来简化您的开发,就像我支持基本配置文件一样。
您可能需要创建custom BinarySecurityToken。标准BinarySecurityToken类扩展了SecurityToken。
关于WCF中的BinarySecuritytoken支持,有许多StackOverflow问题可能有所帮助: