HTTPリクエストヘッダを付加したい
現案件のWebシステムのユーザ認証がクライアントサイドからサーバサイドに変わる。
現状、ユーザ認証はJavaアプレットを使ったシステムによりクライアント側で行う。認証後のユーザ情報はhiddenで持たせて毎回クライアントから業務システムにPOSTさせている(諸事情によりセッションを使うのはナシ)。
しかし、新認証機構ではリバースプロキシ型SSO(シングル・サインオン)となり、認証後のユーザ情報はHTTPリクエストヘッダに乗って来るので、それを業務システム側で受けとる。後続処理は現行との互換性を保つため、クライアントに落としhiddenに埋め込んでおく。
その対応をしたとして、テストのために認証機構のモックアップが欲しい。
HTTPリクエストヘッダに、てきとーな認証情報を埋め込んでくれるようなプロキシを立てればよい。
思いつくのではRubyのWEBrickが適任か? 幸い別プロジェクトでRuby on Railsが開発推進用ポータルサイト作成ツールとして認められているのでRubyは使えるはず。
WEBrickでテスト用サーブレットを書く。標準出力にHTTPヘッダを出力。
require "webrick"serv = WEBrick::HTTPServer.new(:Port => 8888)
serv.mount_proc("/") do |req, res|
p req.request_line
p req.header
p req.body
res.content_type = "text/plain"
res.body = "OK"
endtrap("INT") do
serv.shutdown
endserv.start
続けて、とりあえずGETメソッドのときにHTTPヘッダ項目を追加するプロキシサーブレットを作成。
特異クラスで動的にread onlyのインスタンス変数へのアクセサを追加。
require 'webrick'
require 'webrick/httpproxy'
include WEBrickclass MyProxyServer < HTTPProxyServer
def proxy_service(req, res)
class << req
attr_accessor :raw_header
endif req.request_method == "GET"
req.raw_header = req.raw_header.push("User-Info: HogeHoge\r\n")
p req.raw_header
end
super
end
end
s = MyProxyServer.new(
:BindAddress => '0.0.0.0',
:Port => 8080,
:Logger => WEBrick::Log::new($stderr, WEBrick::Log::DEBUG),
:ProxyContentHandler => nil,
:ProxyVia => true,
:ProxyAddress => '127.0.0.1')
trap('INT') do
s.shutdown
end
s.start
これで両サーブレットを立ち上げ、ブラウザのプロキシ設定をlocalhost:8080に向けて、ブラウザはlocalhost:8888にアクセス。
これでめでたく改ざんできたHTTPヘッダを見られ………ないな。
(ソースを読む)プロキシ側でproxy_serviceが呼ばれる前にリクエストがparseされるのでこの後ヘッダを改ざんしても意味なし。
仕方ないからHTTPProxyServer#runメソッドを丸々コピーして、その中でHTTPRequestのread_headerへ特異メソッドをオーバーライド。
class MyProxyServer < HTTPProxyServer
def run(sock)
while true
res = HTTPResponse.new(@config)
req = HTTPRequest.new(@config)
def req.read_header(socket)
super
@raw_header.push("User-Info: HogeHoge\r\n")
begin
@header = HTTPUtils::parse_header(@raw_header)
rescue => ex
raise HTTPStatus::BadRequest, ex.message
end
end(後略)
これで所望のヘッダは帰ってきた。よきかなよきかな。