Webszolgáltatás hívás kimenő IP címének beállítása

Ma egy olyan webszolgáltatást kellett meghívnom, ami előtt egy tűzfal csak bizonyos IP című kliensekről engedélyezi a hozzáférést. Ez normális esetben nem is szokott gondot okozni, most is megbeszéltem az ottani rendszergazdákkal, hogy milyen IP címről akarom küldeni a kérést, és ők készségesen lyukat ütöttek a tűzfalba. A nehezítést az jelentette, hogy a hívó épp egy szerver, aminek több IP címe van, és persze alapból nem arról ment ki a kérés, ahonnan én akartam. A kérdés tehát, hogy hogyan lehet megadni egy webszolgáltatás hívásnál a hívó IP címét?

A dolog szerencsére megoldható, de nem olyan egyszerűen, mint szeretnénk. A Visual Studio varázslója olyan proxy osztályt generál, ami a SoapHttpClientProtocol ősosztályból származik, aminek persze egy fikarcnyi ide vágó property-je sincsen. Viszont a HTTP híváshoz ő belül a HttpWebRequest osztályt használja, amin szerencsére lehet ilyen jellegű fogódzót találni. Persze csak alapos kereséssel, ugyanis a tulajdonságot úgy hívják, hogy ServicePoint, aminek a BindIPEndPointDelegate tulajdonságát (!) kell beállítani egy delegate-re! Én bizony ezt biztosan nem így csináltam volna, de gondolom jó okuk volt rá, hogy így döntöttek.

Sajnos a belső WebRequest példány szintén nincs kivezetve a SOAP proxy osztályban, így nincs más lehetőségünk, mint a VS által generált proxy osztályból egy újabb osztályt származtatni, és ott felülírni azt a metódust, ami a WebRequest példány előállításáért felelős. Miután ezt így fejben levezette az ember, a kód már meglehetősen rövid:

class MyServiceWrapper : MyVSGeneratedServiceProxyClass
{
  public IPAddress SourceIPAddress { get; set; }

  protected override WebRequest GetWebRequest( Uri uri )
  {
    HttpWebRequest request = (HttpWebRequest) base.GetWebRequest( uri );
    request.ServicePoint.BindIPEndPointDelegate = new BindIPEndPoint(
      delegate( ServicePoint servicePoint, 
                IPEndPoint remoteEndPoint, 
                int retryCount )
      {
        return new IPEndPoint( this.SourceIPAddress, 0 );
      });
    return request;
  }
}

Persze akinek nem jön be ez a tömör névtelen metódusos megoldás, az írhat olvashatóbb kódot két metódusba:

protected override WebRequest GetWebRequest( Uri uri )
{
  HttpWebRequest request = (HttpWebRequest) base.GetWebRequest( uri );
  request.ServicePoint.BindIPEndPointDelegate = 
    new BindIPEndPoint( this.OnBindIPEndPoint );
  return request;
}


private IPEndPoint OnBindIPEndPoint( ServicePoint servicePoint, 
                                     IPEndPoint remoteEndPoint,
                                     int retryCount )
{
  return new IPEndPoint( this.SourceIPAddress, 0 );
}

Végül már csak annyi dolgunk maradt, hogy a Studio által generált osztály helyett a sajátunkat példányosítjuk és beállítjuk a SourceIPAddress tulajdonságot a kívánt IP címre.

Technorati-címkék:
Advertisements

2 thoughts on “Webszolgáltatás hívás kimenő IP címének beállítása

  1. Balássy György Post author

    Szia Zsolt! Bevallom, én nem találtam rá megoldást. Megkérdeztem WCF guru kollégákat és konkrétumok nélkül odáig jutottunk, hogy a WCF minden rész csereberélhető, valami channelt vagy providert vagy hasonlót kellene írni 🙂 Ez így persze nem sok, valakinek esetleg van konkrétabb javaslata?

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s