読者です 読者をやめる 読者になる 読者になる
無料で使えるシステムトレードフレームワーク「Jiji」 をリリースしました!

・OANDA Trade APIを利用した、オープンソースのシステムトレードフレームワークです。
・自分だけの取引アルゴリズムで、誰でも、いますぐ、かんたんに、自動取引を開始できます。

WSDLの取得時に認証が必要だったのです

Share Point ServerのWebサービスにアクセスすると、突然、WSDLの取得時に認証エラーになるようになった。

原因

Webアプリケーションで匿名アクセスの許可を解除したため、WSDLの取得時に認証が必要になっていた。

対応

ということでWSDL取得時に認証情報を渡すようにクライアントを修正。一応、手順はここにある(→soap4r - trac - Accessing BasicAuth? protected WSDL)のだけど、この通りやってもモジュールのバージョン等の問題か、うまく動作しなかったので、ちょっと強引にねじ込んでみた。戦略は以下。

  • WSDL::XMLSchema::Importer#web_clientでWSDL取得時に使用するHTTPクライアントを決定しているので、上書きしてカスタムのクライアントを返すように修正。
  • カスタムのクライアンは、HTTPAccess2::Clientを継承し、
  • WSDLを読み込む前でグローバル変数WSDLのURLを設定してから、ドライバを作る。

うわぁ。せめてスレッドローカル変数にしようよ。

require 'rubygems'
require 'httpclient'
require 'soap/wsdlDriver'

XSD:: Charset.encoding="UTF8"

#Importer#web_clientを上書きして独自のクライアントを使う
module WSDL
module XMLSchema
  class Importer
    def web_client
      @web_client = HttpClientWithAuth
    end
  end
end
end

class WSS
  def initialize( host, port, user, pass )
    @host = host
    @port = port
    @user = user
    @pass = pass
    $moss_user = user
    $moss_pass = pass
  end
  def service( name, target )
    wsdl = "http://#{@host}:#{@port}/#{target}/_vti_bin/#{name}.asmx?WSDL"
    begin
      $wsdl_url = wsdl
      driver = SOAP::WSDLDriverFactory.new(wsdl).create_rpc_driver
      driver.options["protocol.http.basic_auth"] << ["http://#{@host}:#{@port}",@user,@pass]
      return driver
    ensure
      $wsdl_url = nil
    end
  end
end

# 認証情報を設定するカスタムのHTTPクライアント
class HttpClientWithAuth < HTTPAccess2::Client
  def initialize( *args )
    super
    set_basic_auth( $wsdl_url, $moss_user, $moss_pass ) if $wsdl_url
  end
end

これで、匿名アクセス不可のサイトでもWebサービスを呼び出せるはず。


それにしても、WSDLくらいは、認証なしで取得させてくれてもいいんでは、と思うんだけど・・・。APIの呼び出し時に認証が必要とかならわかるんだけどさ。