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:

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

  1. Balássy György Szerző

    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?

Vélemény, hozzászólás?

Adatok megadása vagy bejelentkezés valamelyik ikonnal:

WordPress.com Logo

Hozzászólhat a WordPress.com felhasználói fiók használatával. Kilépés / Módosítás )

Twitter kép

Hozzászólhat a Twitter felhasználói fiók használatával. Kilépés / Módosítás )

Facebook kép

Hozzászólhat a Facebook felhasználói fiók használatával. Kilépés / Módosítás )

Google+ kép

Hozzászólhat a Google+ felhasználói fiók használatával. Kilépés / Módosítás )

Kapcsolódás: %s