2013-08-28 3 views
0

j'ai créé un service avec une telle configuration de liaison:WCF serveur WS-Security

<bindings> 
    <customBinding> 
    <binding name="DefaultBinding"> 
     <textMessageEncoding messageVersion="Soap12" /> 
     <httpTransport /> 
    </binding> 
    </customBinding> 
</bindings> 

Et quand mon service reçoit un message de départ comme celui-ci:

<s:Envelope xmlns:s="http://www.w3.org/2003/05/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"> 
     <UsernameToken> 
     <Username> 
     </Username> 
     <Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">...</Password> 
     <Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">KWVa4abCrEemOMT55VEZkgIAAAAAAA==</Nonce> 
     <Created xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2013-08-28T13:29:05.966Z</Created> 
     </UsernameToken> 
    </Security> 
    ... 

Il produit une erreur:

Le l'en-tête 'Sécurité' de l'espace de noms 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' n'a pas été compris ...

J'ai aussi essayé:

<wsHttpBinding> 
    <binding name="DefaultBinding"> 
     <security mode="Message" /> 
    </binding> 
</wsHttpBinding> 

Comment puis-je traiter cet en-tête ou de l'ignorer?


Mise à jour

Comme je l'ai compris que j'ai besoin nom d'utilisateur sur le transport non sécurisé, donc j'ai essayé:

<customBinding> 
    <binding 
     name="DefaultBinding"> 
     <textMessageEncoding messageVersion="Soap12" /> 
     <security authenticationMode="UserNameOverTransport" allowInsecureTransport="True"> 
     </security> 
     <httpTransport> 

     </httpTransport> 
    </binding> 
</customBinding> 

J'ai essayé aussi CUB:

<bindings> 
    <clearUsernameBinding> 
    <binding name="myClearUsernameBinding" messageVersion="Soap12"> 
    </binding> 
    </clearUsernameBinding> 
</bindings> 

deux se termine par erreur sur le client: une erreur s'est produite lors de la vérification de la sécurité du message. Mais cela fonctionne avec le client de test CUB. Quel pourrait être le problème?

L'enveloppe de CUB est header.

Client de test header.

Répondre

1

solution était simple:

  1. Créer un comportement de service
  2. Créer l'envoi inspecteur un message
  3. Ajouter créé le comportement de service au serveur

Et puis juste analyser ou tout simplement supprimer utilisé "mustUnderstand" en-têtes.

Étape 1:

public class WSSecurityBehavior : IServiceBehavior { 
    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { 
    } 

    public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, 
     Collection<ServiceEndpoint> endpoints, 
     BindingParameterCollection bindingParameters) { 
    } 

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { 
     var endpoints = serviceHostBase 
      .ChannelDispatchers 
      .Cast<ChannelDispatcher>() 
      .SelectMany(dispatcher => dispatcher.Endpoints); 

     foreach (var endpoint in endpoints) 
      endpoint.DispatchRuntime.MessageInspectors.Add(new WSSecurityInspector()); 
    } 
} 

Étape 2:

public class WSSecurityInspector : IDispatchMessageInspector { 
    public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) { 
     var headerPosition = request.Headers.FindHeader("Security", 
      "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"); 

     if (headerPosition > -1) 
      request.Headers.RemoveAt(headerPosition); 

     return null; 
    } 

    public void BeforeSendReply(ref Message reply, object correlationState) { 
    } 
} 

Étape 3:

Host.Description.Behaviors.Add(new WSSecurityBehavior()); 
0

Vous avez une discordance dans la structure/contrat de savon que vous échangez entre le client et l'hôte. La structure des messages échangés entre le client et l'hôte (y compris l'espace de noms) doit correspondre exactement. Si ce n'est pas le cas, vous obtenez cette erreur.

Ce que vous voulez faire, c'est faire fonctionner Fiddler sur votre hôte. Ensuite, en exécutant Fiddler en tant que proxy man-in-the-middle, renvoyez la requête à partir de votre ordinateur client. Lorsque la requête/réponse est terminée, examinez les messages dans Fiddler, en particulier l'espace de noms et structurez les différences entre la requête et la réponse et vous devriez trouver le problème.

0

Le client essaie de s'authentifier auprès de votre serveur à l'aide de l'utilisateur/réussite au niveau du message. Vous devez décider si ce comportement est attendu, auquel cas vous devez configurer votre service pour l'authentification du nom d'utilisateur. Il ne s'agit pas simplement de définir une liaison, vous devez décider comment authentifier les utilisateurs (par exemple via une base de données, des informations d'identification Windows, etc.). Une fois que vous savez que vous devriez être en mesure d'utiliser un liant comme ceci:

 <customBinding> 
      <binding name="NewBinding0"> 
       <textMessageEncoding /> 
       <security authenticationMode="UserNameOverTransport"> 
        <secureConversationBootstrap /> 
       </security> 
       <httpsTransport /> 
      </binding> 
     </customBinding> 

Je ne peux pas être sûr que ce soit ce que vous avez besoin puisque vous n'avez pas publié l'enveloppe complète du savon. Vous devrez peut-être définir l'attribut messageVersion sur l'élément de codage de texte ou utiliser CUB en l'absence de SSL. Ensuite, vous devez configurer comment vous allez vérifier le nom d'utilisateur. Un exemple is here.

+0

Oui, il est Validé pour le client d'envoyer le nom d'utilisateur/pass sur http sans ssl. À ce stade, le service doit l'accepter sans vérifier. J'ai essayé CUB, cela a fonctionné avec le client de test, mais échoué avec le client existant: {"Une erreur est survenue lors de la vérification de la sécurité du message."} J'ai comparé les en-têtes d'evelope: CUB a les éléments suivants: Timestamp, Expires, UsernameToken, Nom d'utilisateur , Mot de passe Mine a: Nom d'utilisateur, mot de passe, Nonce, Créé – therg

+0

s'il vous plaît publier des exemples d'un travail et un message de fialing –

+0

maintenant je vois que vous l'avez publié. vous devez activer wcf trace sur le serveur pour voir l'erreur exacte. http://blogs.msdn.com/b/madhuponduru/archive/2006/05/18/601458.aspx –

0

vous pouvez utiliser basicHttpBinding, télécharger le project and sample code de ce poste pour le mot de passe digérer dans WCF PasswordDigest Auth c'est ma configuration avec cette implémentation (j'ai édité du code pour custo m besoins mais cette solution fonctionne bien).

Créer une reliure:

<bindings> 
    <basicHttpBinding> 
    <binding name="securityBinding"> 
     <security mode="TransportWithMessageCredential"> 
     <message clientCredentialType="UserName"/> 
     </security> 
    </binding> 
    </basicHttpBinding> 
</bindings> 

Et après un comportement ensemble

<behavior name="securityBehavior"> 
     <DataMessageTracer/>  
     <serviceCredentials type="WCF.SecurityExtensions.ServiceCredentialsEx, WCF.SecurityExtensions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"> 
     <serviceCertificate findValue="hypori2.zed.pa" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/> 
     <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="MyService.Utils.PassValidator, MyService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/> 
     </serviceCredentials> 
     <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/> 
     <serviceDebug includeExceptionDetailInFaults="false"/> 
    </behavior> 
    </serviceBehaviors>