2016-08-24 4 views
1

WS-Security 1.1 を使用するWebサービスを呼び出すためのクライアントを作成しようとしています。彼らはWSDLを提供し、Visual Studioでコードを生成しました。ここでWs-Security 1.1ヘッダーのセキュリティが理解されない

(UPDATE)はフィドラーを通して私の要求

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> 
    <s:Header> 
    ... 
     <Security s:mustUnderstand="1" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> 
      <u:Timestamp u:Id="7c10648f-984d-4920-849e-b0afb586f871"> 
       <u:Created>2016-08-24T13:08:06.118Z</u:Created> 
       <u:Expires>2016-08-24T14:08:06.118Z</u:Expires> 
      </u:Timestamp> 
      <o:UsernameToken> 
       <o:Username>actualUsername</o:Username> 
       <o:Password>realPassword</o:Password> 
      </o:UsernameToken> 
     </Security> 
    </s:Header> 
    <s:Body xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 

をあるここで結合

<basicHttpBinding> 
    <binding name="BasicHttpBinding_IConnectService"> 
     <security mode="TransportWithMessageCredential" /> 
    </binding> 
</basicHttpBinding> 

ですが、私は私がしたいデータが返さなっていることがわかります。

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> 
    <s:Header> 
     <o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> 
      <u:Timestamp u:Id="_0"> 
       <u:Created>2014-05-02T14:02:46.988Z</u:Created> 
       <u:Expires>2014-05-02T14:07:46.988Z</u:Expires> 
      </u:Timestamp> 
     </o:Security> 
    </s:Header> 
    <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    .... 
    The data I really want 

はただし、Visual Studioで、私はこのエラーを取得:

The header 'Security' from the namespace ' http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd ' was not understood by the recipient of this message, causing the message to not be processed. This error typically indicates that the sender of this message has enabled a communication protocol that the receiver cannot process. Please ensure that the configuration of the client's binding is consistent with the service's binding.

は、どのように私はこのエラーを修正しますか?データが戻ってくるのを考えると、構成上の問題のように思えます。

+0

あなたのクライアントがどのように見えるの結合んか? basicHttpBindingまたはwsHttpBindingを使用していますか? – Michael

+0

私はbasicHttpBindingを使用しています。私はちょうど質問に詳細を追加しました。 – beans

+0

私は同じエラーで同じ問題を抱えています。 – Musketyr

答えて

0

解決策が見つかりましたが、修正する必要がありました。

public class CustomCredentials : ClientCredentials 
{ 
    public CustomCredentials() 
    { } 

    protected CustomCredentials(CustomCredentials cc) 
     : base(cc) 
    { } 

    public override System.IdentityModel.Selectors.SecurityTokenManager CreateSecurityTokenManager() 
    { 
     return new CustomSecurityTokenManager(this); 
    } 

    protected override ClientCredentials CloneCore() 
    { 
     return new CustomCredentials(this); 
    } 
} 
public class CustomSecurityTokenManager : ClientCredentialsSecurityTokenManager 
{ 
    public CustomSecurityTokenManager(CustomCredentials cred) 
     : base(cred) 
    { } 

    public override System.IdentityModel.Selectors.SecurityTokenSerializer CreateSecurityTokenSerializer(System.IdentityModel.Selectors.SecurityTokenVersion version) 
    { 
     return new CustomTokenSerializer(System.ServiceModel.Security.SecurityVersion.WSSecurity11); 
    } 
} 
public class CustomTokenSerializer : WSSecurityTokenSerializer 
{ 
    public CustomTokenSerializer(SecurityVersion sv) 
     : base(sv) 
    { } 

    protected override void WriteTokenCore(System.Xml.XmlWriter writer, System.IdentityModel.Tokens.SecurityToken token) 
    { 
     UserNameSecurityToken userToken = token as UserNameSecurityToken; 

     string tokennamespace = "o"; 

     DateTime created = DateTime.UtcNow; 
     string createdStr = created.ToString("yyyy-MM-ddThh:mm:ss.fffZ"); 

     Random r = new Random(); 
     var nonce = Convert.ToBase64String(Encoding.ASCII.GetBytes(GetSHA1String(created + r.Next().ToString()))); 


     // string password = GetSHA1String(nonce + createdStr + userToken.Password); 

     writer.WriteRaw(string.Format(
     "<{0}:UsernameToken u:Id=\"" + "UsernameToken-ABCD" + 
     "\" xmlns:u=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\">" + 
     "<{0}:Username>" + userToken.UserName + "</{0}:Username>" + 
     "<{0}:Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText\">" + 
     userToken.Password + "</{0}:Password>" + 
     "<{0}:Nonce EncodingType=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary\">" + 
     nonce + "</{0}:Nonce>" + 
     "<u:Created>" + createdStr + "</u:Created></{0}:UsernameToken>", tokennamespace)); 
    } 

    protected string GetSHA1String(string phrase) 
    { 
     UTF8Encoding encoder = new UTF8Encoding(); 
     SHA1CryptoServiceProvider sha1Hasher = new SHA1CryptoServiceProvider(); 
     byte[] hashedDataBytes = sha1Hasher.ComputeHash(encoder.GetBytes(phrase)); 
     return ByteArrayToString(hashedDataBytes); 
    } 

    protected String ByteArrayToString(byte[] inputArray) 
    { 
     StringBuilder output = new StringBuilder(""); 
     for (int i = 0; i < inputArray.Length; i++) 
     { 
      output.Append(inputArray[i].ToString("X2")); 
     } 
     return output.ToString(); 
    } 

} 
public static YOURContractClient CreateRealTimeOnlineProxy(string url, string username, string password) 
    { 
     CustomBinding binding = new CustomBinding(); 

     var security = TransportSecurityBindingElement.CreateUserNameOverTransportBindingElement(); 
     security.IncludeTimestamp = false; 
     security.DefaultAlgorithmSuite = SecurityAlgorithmSuite.Basic256; 
     security.AllowInsecureTransport = true; 
     security.MessageSecurityVersion = MessageSecurityVersion.WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10; 

     var encoding = new TextMessageEncodingBindingElement(); 
     encoding.MessageVersion = MessageVersion.Soap11; 

     var transport = new HttpTransportBindingElement(); 
     transport.MaxReceivedMessageSize = 20000000; // 20 megs 

     binding.Elements.Add(security); 
     binding.Elements.Add(encoding); 
     binding.Elements.Add(transport); 

     YOURContractClient client = new YOURContractClient(binding, new EndpointAddress(url)); 
     client.ChannelFactory.Endpoint.Behaviors.Remove<System.ServiceModel.Description.ClientCredentials>(); 
     client.ChannelFactory.Endpoint.Behaviors.Add(new CustomCredentials()); 

     client.ClientCredentials.UserName.UserName = username; 
     client.ClientCredentials.UserName.Password = password; 

     return client; 
    } 

それを使用します。

var cl = CreateRealTimeOnlineProxy(URL, USER_NAME, PASSWORD); 
関連する問題