2010-10-07 3 views
2

J'ai créé un workflowservice en .net 4.0exception show de service WCF lors de la sécurisation de service avec l'authentification wsHttpBinding et nom d'utilisateur

Je suis en train d'obtenir ce (WCF) service et utilisé le lien suivant pour voir comment cela se fait.

J'ai suivi les instructions, cependant quand un comportement de service défini fonctionne bien. La configuration est comme ceci:

<behaviors> 
     <serviceBehaviors> 
     <behavior> 
     <serviceCredentials name="ServiceBehavior"> 
      <userNameAuthentication userNamePasswordValidationMode="MembershipProvider" 
       membershipProviderName="AspNetSqlMembershipProvider" /> 
      </serviceCredentials> 
      <serviceMetadata httpGetEnabled="true" /> 
      <serviceDebug includeExceptionDetailInFaults="false" /> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 

Mes fixations est spécifié comme ceci:

<bindings> 
     <wsHttpBinding> 
     <binding name="CentralAdminBinding"> 
      <security mode="TransportWithMessageCredential"> 
      <transport clientCredentialType="None"/> 
      <message clientCredentialType="UserName"/> 
      </security> 
     </binding> 
     </wsHttpBinding> 
    </bindings> 

Quand j'appelle l'URL pour voir le xamlx pour le service, l'erreur suivante apparaît:

Impossible de trouver une adresse de base correspondant au schéma https pour le point de terminaison avec la liaison BasicHttpBinding. schémas d'adresse de base sont enregistrés [http]

Comment puis-je gérer cette erreur? Je n'utilise pas du tout le https mais je reçois toujours une erreur.

J'ai également essayé de passer à basichttpbinding au lieu de wshttp, mais cela donne une erreur similaire.

Lors de la modification du mode de sécurité en message, l'erreur suivante s'affiche: Le certificat de service n'est pas fourni. Spécifier un certificat de service dans ServiceCredentials

Est-il possible d'utiliser la configuration sans le certificat?

Répondre

3

moyens TransportWithMessageCredential que vous souhaitez utiliser la sécurité du transport et envoyer des informations d'identification dans le message. La sécurité du transport dans ce cas signifie HTTPS. La première version de WCF exigeait que le nom d'utilisateur et le mot de passe ne puissent être utilisés qu'avec une communication sécurisée. Plus tard, MS a publié un correctif qui permet de contourner le HTTPS, mais il n'est pas recommandé. Dans .NET 4.0, le correctif est inclus directement.

Si vous souhaitez utiliser les informations d'identification de message sans communication sécurisée, vous devez créer la même liaison personnalisée à ceci:

<bindings> 
    <customBinding> 
    <binding name="HttpWithAuthentication"> 
     <security authenticationMode="UserNameOverTransport" allowInsecureTranpsort="true" /> 
     <context /> <!-- needed for durable worklfows --> 
     <textMessageEncoding messageVersion="Soap12Addressing10" /> 
     <httpTransport /> 
    </binding> 
    </customBinding> 
</bindings> 

problème allowInsecurTransport est qu'il est une « solution rapide » qui n'intègre pas tous WCF fonctionnalités.Ainsi, par exemple, lorsque vous l'utilisez, votre service n'est pas capable de générer des WSDL/métadonnées car cette partie nécessite toujours une communication sécurisée.

+0

Super! Donc, finalement, ils l'ont permis ... Je ne savais pas à ce sujet. Je me suis cogné la tête contre le mur pour trouver un moyen mais il n'y en avait pas alors j'ai écrit le mien. – Aliostad

3

Vous avez utilisé TransportWithMessageCredential, ce qui signifie HTTPS obligatoire. Vous devez donc soit modifier votre paramètre de sécurité, soit activer SSL.

WCF ne permet pas d'authentification en texte clair sur http, il nécessite https et ce comportement est voulu - je ne suis pas d'accord mais bon, je ne suis pas Microsoft.

Si vous devez activer l'authentification en texte clair, vous devez créer le message manuellement dans l'inspecteur de messages.

MISE À JOUR

Voici était ma mise en œuvre (ce qui est une preuve grossière et que concept), mais l'autre réponse est meilleure (prise en charge intégrée dans WCF 4.0):

[Serializable()] 
    public class ConsoleMessageTracer : BehaviorExtensionElement, 
    IClientMessageInspector ,IEndpointBehavior, System.Configuration.IConfigurationSectionHandler 
    { 

    private string _userName = string.Empty; 
    private string _password = string.Empty; 

    [XmlAttribute()] 
    public string UserName 
    { 
     get { return _userName; } 
     set { _userName = value; } 
    } 

    [XmlAttribute()] 
    public string Password 
    { 
     get { return _password; } 
     set { _password = value; } 
    } 


    private Message TraceMessage(MessageBuffer buffer) 
    { 
     Message msg = buffer.CreateMessage(); 
     Console.WriteLine("\n{0}\n", msg); 
     return buffer.CreateMessage(); 
    } 


    public void AfterReceiveReply(ref Message reply, object 
     correlationState) 
    { 
     reply = TraceMessage(reply.CreateBufferedCopy(int.MaxValue)); 
    } 

    public object BeforeSendRequest(ref Message request, 
     IClientChannel channel) 
    { 

     request.Headers.Add(MessageHeader.CreateHeader("Security", 
     "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", 
     tt, true, "http://www.isban.es/soap/actor/wssecurityUserPass") 
     ); 

     return null; 
    } 

    public override Type BehaviorType 
    { 
     get { return this.GetType(); } 
    } 

    protected override object CreateBehavior() 
    { 
     return this; 
    } 

    #region IEndpointBehavior Members 

    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) 
    { 
     return; 
    } 

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) 
    { 
     clientRuntime.MessageInspectors.Add(new ConsoleMessageTracer()); 
     //foreach (ClientOperation op in clientRuntime.Operations) 
     // op.ParameterInspectors.Add(new ConsoleMessageTracer()); 
    } 

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) 
    { 
     //endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new ConsoleMessageTracer()); 
     //foreach (DispatchOperation op in endpointDispatcher.DispatchRuntime.Operations) 
     // op.ParameterInspectors.Add(new ConsoleMessageTracer()); 
    } 

    public void Validate(ServiceEndpoint endpoint) 
    { 
     return; 
    } 

    #endregion 

    #region IConfigurationSectionHandler Members 

    public object Create(object parent, object configContext, XmlNode section) 
    { 
     return null; 
    } 

    #endregion 
    } 

    [DataContract(Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd")] 
    //[DataContract(Namespace = "")] 
    [Serializable()] 
    public class UserNameTokenToken 
    { 
     [DataMember()] 
     public UserNameToken UsernameToken; 

     public UserNameTokenToken(UserNameToken token) 
     { 
      UsernameToken = token; 
     } 
    } 

    [DataContract(Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd")] 
    //[DataContract(Namespace = "")] 
    [Serializable()] 
    public class UserNameToken 
    { 
     [DataMember(Order = 1)] 
     public string Username = string.Empty; 
     [DataMember(Order = 2)] 
     public string Password = string.Empty; 

     public UserNameToken(string uname, string pass) 
     { 
      Username = uname; 
      Password = pass; 
     } 

    } 
+0

Lorsque je n'utilise que Message, je devrais pouvoir utiliser http? – Jan

+2

Le message ne se traduit pas par le mot de passe du nom d'utilisateur. Ce sont les certificats et tout ça. C'est frustrant que la WCF ne le permette pas. Je vais y mettre une partie de mon code pour faire le mot de passe du nom d'utilisateur - ce soir. – Aliostad

+0

@Jan J'ai mis à jour ma réponse mais l'autre réponse est meilleure. – Aliostad

Questions connexes