Fork me on GitHub

Jruby Ssl経由でsoapを使う

  • Jan 05, 2010

categoryプラグインは存在しません。

概要

JRubyのSSL実装は色々問題を抱えていて、一筋縄ではいきません。私がうまくいった方法をメモしておきます。

環境

  • JRuby 1.1.5
  • jruby-openssl 0.6
  • httpclient 2.1.5.2
  • Ubuntu 9.04 (amd64)

手順

クライアント側

クライアント側からSSLを利用する場合は、

  1. webrick/https を最初にrequireする
  2. optionsを指定する

の2点を気をつければ問題ありません。httpclientはgem installで入れておきます。

SOAP::RPC::Driverを使った接続はこんな感じで使います。

require 'webrick/https'
require 'soap/rpc/driver'

conn = SOAP::RPC::Driver.new("https://localhost:443")
conn.options["protocol.http.ssl_config.verify_mode"] = nil
conn.add_method("echo", "message")
puts "result=", conn.echo("test")

注意が必要なのは、optionsでssl_configを指定するやり方は、CRuby 1.8.7(オリジナルRuby)では動作しないという点です。これは私も何故だかわかりません。

サーバ側

サーバ側でクライアント認証をせずにSSLを使うには、JRuby内のwebrickのメソッドをオーバーライドします。

これはおそらくjruby-opensslのバグなので、そのうち修正されたら元に戻す必要があります。またバージョンによっては動作しない可能性もありますので、注意が必要です。

具体的にはこんな感じでparseメソッドをオーバーライドして、クライアントのcertificateを取得しないようにします。

require 'webrick/https'
require 'soap/rpc/httpserver'
require 'soap/rpc/driver'

module WEBrick
 class HTTPRequest
   attr_reader :cipher, :server_cert, :client_cert
   def parse(socket=nil)
     if socket.respond_to?(:cert)
       @server_cert = socket.cert || @config[:SSLCertificate]
       @cipher      = socket.cipher
     end
     orig_parse(socket)
   end
 end
end

あとは通常どおり、

class SOAPServer < SOAP::RPC::HTTPServer
 def on_init
   add_method(self, 'echo', 'message')
 end
 def echo(message)
   return message
 end
end

server_cert = ..省略
server_key = ..省略
server = SOAPServer.new(
 :BindAddress => "0.0.0.0",
 :Port => 443,
 :AccessLog => [],
 :SSLEnable => true,
 :SSLCertificate => server_cert,
 :SSLPrivateKey => server_key,
 :SSLVerifyClient => nil,
 :SSLCertName => nil
)
new_thread = Thread.new \{ server.start \}

という感じでサーバを起動すれば使えます。気をつけないといけないのは、CRubyでは自己署名していないCertificateでもエラーは出ませんが、JRubyでは署名がないとエラーになってしまうという点です。

組み合わせ毎の動作

JRuby server + JRuby 1.1 client

  • オプション指定なし
    • エラー
    </ul>

    /usr/lib/jruby1.1/lib/ruby/1.8/soap/streamHandler.rb:183:in `send_post': certificate verify failed (OpenSSL::SSL::SSLError)

    • オプション指定あり
      • 正常動作
      </ul>

      JRuby server + Ruby 1.8.7 client

      • オプション指定なし
        • warning
        </ul>

        warning: peer certificate won't be verified in this SSL session

        • オプション指定あり
          • エラー
          </ul>

          /usr/lib/ruby/1.8/soap/httpconfigloader.rb:64:in `set_ssl_config': SSL not supported (NotImplementedError)

          JRuby server + JRuby 1.2 client

          • オプション指定なし
            • エラー
            </ul>

            /usr/lib/jruby1.2/lib/ruby/gems/1.8/gems/httpclient-2.1.5.2/lib/httpclient/session.rb:247:in `ssl_connect': certificate verify failed (OpenSSL::SSL::SSLError)

            • オプション指定あり
              • 正常動作
              </ul>

              commentプラグインは存在しません。