2013-10-01 6 views
5

Я прочитал много статей и ответов, но я не смог его обработать.Как добавить заголовок SOAP Security

Я использую .NET Framework 4.0 в своем проекте. Итак, я сначала добавил WebService как ссылку на службу и получаю привязки в своем app.config. И я буду перечислять мои попытки


Попытка # 1

Я экземпляр службы, как это и добавил полномочия:

На App.Config

<binding name="SubscriptionWSImplServiceSoapBinding" > 
    <security mode="TransportWithMessageCredential"> 
    <transport clientCredentialType="Basic"/> 
    </security> 
</binding> 

SubscriptionWSImplServiceClient ClientWs = new SubscriptionWSImplServiceClient(); 
ClientWs.ClientCredentials.UserName.UserName = "some-username"; 
ClientWs.ClientCredentials.UserName.Password = "some-password"; 

var SomeResposne = ClientWs.RunMethod(); //I have exception at this point 

Я получаю исключение, как показано ниже:

System.ArgumentException: The provided URI scheme 'http' is invalid; 
expected 'https'. Parameter name: via at System.ServiceModel.Channels 

Исключения говорят, что URL-адрес веб-службы должен быть HTTPS, но данный URL-адрес веб-службы - это HTTP, а не HTTPS.

Но я не возражал против HttpS и пошел на вторую попытку.


Попытка # 2

Как указано в this answer Я попытался, как показано ниже:

BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportWithMessageCredential); 
binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName; 
CustomBinding customBinding = new CustomBinding(binding); 
SecurityBindingElement element = customBinding.Elements.Find<SecurityBindingElement>(); 
element.IncludeTimestamp = false; 

EndpointAddress address = new EndpointAddress("https://www.GivenServiceUrl.com/WebService"); //Note that the url does not end as ..svc or ..asmx! Just the name like this with no dot or extension 


SubscriptionWSImplServiceClient ClientWs = new SubscriptionWSImplService(customBinding, address); 
ClientWs.ClientCredentials.UserName.UserName = "some-username"; 
ClientWs.ClientCredentials.UserName.Password = "some-password"; 

var SomeResposne = ClientWs.RunMethod(); //I have exception at this point 

я получаю исключение, как показано ниже:

System.ServiceModel.Security .SecurityNegotiationException: не удалось установить доверительные отношения для SSL/TLS защищенного канала с полномочиями «https://www.GivenServiceUrl.com/WebService»

Поэтому я пошел на мою 3-й попытку, который я дал ссылку, как WebReference не так ServiceReference на моем проекте.


Попытка # 3

SubscriptionWSImplService ClientWs2 = new SubscriptionWSImplService(); 
var SomeResposne = ClientWs.RunMethod(); //I have exception at this point 

Я не знаю, как отправить заголовок безопасности в этой точке.

я получаю исключение, как показано ниже:

System.Web.Services.Protocols.SoapHeaderException: An error was 
discovered processing the <wsse: Security> header 

Но здесь, я не мог бы добавить необходимый заголовок. Не могли бы вы мне помочь?


Попытка 1 или попытка 2 или 3 Попытаться, который следует использовать также учитывая то, что я использую Framework 4.0? И как я могу решить проблему?

Согласно документу окончательный запрос SOAP должен быть похож на это:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sub="http://subscription.services.ws.fourplay.com.tr/"> 
    <soapenv:Header> 
     <wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> 
     <wsse:UsernameToken wsu:Id="UsernameToken-12" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> 
      <wsse:Username>admin</wsse:Username> 
      <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">123456</wsse:Password> 
      <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">1lcj+WbCMlrPyhcud4QxiQ==</wsse:Nonce> 
      <wsu:Created>2012-06-05T10:23:26.879Z</wsu:Created> 
     </wsse:UsernameToken> 
    </wsse:Security> 
    </soapenv:Header> 
    <soapenv:Body> 
     <sub:RunMethod> 
     <!--Optional:--> 
     <sub:opaque id>555555555</sub:opaque id> 
     <sub:params> 
      <!--Optional:--> 
      <name>GUID</name> 
      <!--Optional:--> 
      <value>2fc4ce1d-645e-41f4-811e-28510a02a17f </value> 
     </sub:params>  
</sub: RunMethod > 
+1

Вы не сможете сделать это с помощью Web Reference. Они не поддерживают WS-Security –

ответ

5

Я решил ее с помощью WCF без каких-либо полномочий, объявленных. Я сделал это, построив свой собственный заголовок, я получил помощь от этой ссылки

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

и как использовать заголовок я получил его от этого link.

+0

Когда вы говорите, что вы использовали WCF ... что именно вы имеете в виду? Наверное, я знаком с добавлением «Web Reference» в wsdl. Преобразуем ли мыльный прокси-сервер VS в службу WCF или что-то еще? – Terry

+2

Не используйте ссылку «Добавить веб-ссылку». Это традиционная технология «ASMX», которая не должна использоваться для новой разработки. –

+0

Ваша _createdDate.ToString (...) использует недопустимую строку формата, которая генерирует дату типа «YYYY-10-DDT06: 10: 59» ... Вместо этого используйте _createdDate.ToString («o») –

0

У меня была такая же проблема, как и Первая попытка вопроса, и мне нужно было иметь такой же результат, как и вопрос. Ответ отлично, но только для того, чтобы улучшить приведенный выше ответ, или я должен сказать, чтобы объединить ответ со ссылкой, я сделал следующее.

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([email protected],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 
    } 
} 
Смежные вопросы