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の呼び出し時に認証が必要とかならわかるんだけどさ。