mod_mrubyの認証機能について(応用編2)

実際にmod_mrubyの認証を使ってみる応用編その2です。
今回もRedmineを題材に認証を連動させてみます。

Redmineのユーザ情報を使って認証する方法その2として、RedmineのRESTインタフェースをHTTP経由で呼び出して認証する方法を紹介します。
HTTP経由呼び出しなので、Redmine以外でも簡単に応用がききます。

HTTPで認証を他システムへ委譲

準備:

  • Socketを使うので、iij/mruby版のmod_mrubyをApacheに組み込んでおきます。
  • Basic認証をするので、Redmineの認証と連動したい<Location>または<Directory>にmod_mrubyのBasic認証定義を書いておきます。
  • Redmineの設定「RESTによるWebサービスを有効にする」をチェックして使用可能にしておきます。

考え方:

  • RedmineのRESTインタフェースをHTTP経由でアクセスし、ステータスコードを取得
  • 取得したステータスコードが200(OK)なら認証成功。それ以外は失敗。

スクリプトは以下のようになります。全文はgistにあげました。

HOST="127.0.0.1"
PORT=80
PATH="/redmine/users/current.xml"

def main
  anp = Apache::AuthnProvider.new
  credentials = [[anp.user, anp.password].join(":")].pack("m").gsub("\n", "")
  request = {}
  request['User-Agent'] = "mruby_authn_http/0.1"
  request['Authorization'] = "Basic #{credentials}"
  http = SimpleHttp.new(HOST, PORT)
  ret = http.request("HEAD", PATH, request)

  if ret.code == 200
    return(Apache::AuthnProvider::AUTH_GRANTED)
  else
    return(Apache::AuthnProvider::AUTH_DENIED)
  end

rescue => e
  Apache.errlogger(3, "mruby_authn_http An exception occured : #{e.inspect}")
  return Apache::AuthnProvider::AUTH_DENIED
end

##
# Simple Http
# from https://gist.github.com/3765572

*SNIP*

Apache.return(main())

この実装は本当に単純で、Basic認証付きでRedmineのRESTインタフェースを呼び出しているだけです。
Basic認証は、Authorizationヘッダに”BASIC ユーザ:パスワードをBase64化した改行なし文字列”を設定すると実現できます。
ステータスコードしか興味ないので、HEADメソッドでヘッダだけ取得します。
RedmineのLocationを”/redmine”していた場合、”/redmine/users/current.xml”は、ログインユーザの情報を取得するURLになります。
このリクエストに200を返せば、そのユーザは存在し、かつパスワードが有効だということになります。

SimpleHTTPは@matsumotoryさんのgist投稿から拝借させていただきました。

このようにmod_mrubyの認証機能を使うと、非常にシンプルに他システムの認証を拝借することができます。

さて、応用編はこれで終わりです。次回は実装編を書きます。

Nazy の紹介

A software engineer.
カテゴリー: mruby, Programming タグ: パーマリンク