2013-05-27 4 views
1

이 블로그를 사용하여 nonce 암호 텍스트를 구현하고 있습니다. http://benpowell.org/supporting-the-ws-i-basic-profile-password-digest-in-a-wcf-client-proxy/ 나는 다른 많은 블로그를 보았지만 이것을 시험해보고 싶다.2 개의 보안 태그를 생성하는 바인딩, nonce가있는 X509의 + usernmaetoken을 가진 soap xml

이것은 내가 지금까지해온 것입니다. 먼저 서비스에 대한 통제권이 없습니다. 나는 단지 소비자 일 뿐이다.

passwordtextmessaginspector는 나가는 메시지를 수정할 수있는 IClientMessageInspector를 구현합니다. 이 경우 nonce를 포함한 메시지에 usernametoken을 추가하고 싶습니다. 그래서 Ben은 BeforeRequestSent에서 WSE를 사용합니다. using 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 
    } 
} 

내 비누 요청이 이미이 명하는 X509Certificates 있습니다. 나는이 usernametoken을 보내기 전에 nonce로 추가하는 것이다. 내 프록시 클라이언트가 그래서 PasswordTextBehavior이 proxy.endpoint.behavior.add 새로운 행동 (passwordtextbehavior)를 추가하고

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; 
} 

과 같은 방법 이입니다.

이렇게하는 것이 올바른 방법입니까? 나는 두 개의 보안 섹션을 얻고있다.

내 헤더는

<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#"> 

하나의 보안 태그와 하나의 mustUnderstand에가 있어야합니다.

공급 업체 샘플

<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

당신은 분명히 WCF가 추적이 같은 문제를 추적 할 수있는 bext 방법 인 실행해야합니다.

이제 예상 메시지 출력 예가 필요합니다. 그로부터 체계적으로 거꾸로 작업을 시작할 수 있습니다.

인증서를 사용하여 서명을 작성해야합니다. 원한다면 WSE classes을 사용하여 기본 프로파일을 지원했던 것처럼 개발을 단축 할 수 있습니다.

custom BinarySecurityToken을 만들어야 할 수 있습니다. 표준 BinarySecurityToken 클래스는 SecurityToken을 확장합니다. WCF에서 BinarySecuritytoken 지원에 관해서

, 도움이 될 수 StackOverflow의 질문들 중 하나입니다 : 답장을

  1. Accepting both UsernameToken and BinarySecurityToken in WCF customBinding
  2. How do i sign a BinarySecurityToken in soap message
  3. http://threeisit.com/post/WCF2c-Interop2c-and-the-elusive-BinarySecurityToken.aspx
+0

덕분에, 편집 내 질문. 마지막 코드 부분을 참조하십시오. 추적 XML 파일에서 가져온 것입니다. 나는 이것이 custombinding 때문에 두 번째 보안 태그 이진 토큰을 포함하고 WSE 클래스가있는 BeforeSendRequest가 첫 번째 보안 인 을 추가합니다. 어떻게 든이 두 보안 태그를 병합 할 수 있습니까? – user575219

+0

@ user575219 updated 대답 – Junto

+0

답을 고맙습니다. 공급 업체의 샘플 요청으로 내 질문을 편집했습니다. nonce가있는 바이너리 보안 토큰 + usernametoken이 필요합니다. – user575219