vendredi 20 mai 2011

Client WCF et HTTP Basic Authentification

WCF propose 2 protocoles pour cela : BasicHttpBinding et WSHttpBinding avec des caractéristiques différentes. Parmi celles-ci, la version SOAP des messages échangés doit être de version SOAP 1.1 pour  BasicHttpBinding et SOAP 1.2 pour WSHttpBinding.
En partant du principe, que le web service cible est implémenté en SOAP 1.2, la seule solution devient WSHttpBinding. Sauf que … WSHttpBinding impose soit une sécurité sur le transport (SSL) ou sur le message (certificat X.509). Il n’existe donc aucune solution dans WCF pour utiliser un service web basé sur HTTP Basic Auth sans protection (très mauvaise pratique, je l’accorde …).
La seule solution est donc un CustomBinding surchargeant BasicHttpBinding en lui imposant comme version de message SOAP 1.2.
public class MyBasicHttpBinding : BasicHttpBinding
    {
        public override BindingElementCollection CreateBindingElements()
        {
            Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
            Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
            BindingElementCollection bc = base.CreateBindingElements();
            bc.Remove(bc.Find<textmessageencodingbindingelement>());
            //Transport binding element must be the last
            bc.Insert(0, new TextMessageEncodingBindingElement { MessageVersion = MessageVersion.Soap12 });
            return bc;
        }
    }

Pour le client :
var client = new MyWebserviceClient(new MyBasicHttpBinding(), new EndpointAddress("http://localhost:8090/MyWebservice"));
client.ClientCredentials.UserName.UserName = "my_user";
client.ClientCredentials.UserName.Password = "my_key";
client.doSomething();