ククログ

株式会社クリアコード > ククログ > Windows認証でRedmineに自動ログイン

Windows認証でRedmineに自動ログイン

RedmineでSSOしたい阿部です。

IISでリバースプロキシができてREMOTE_USERを使ってRedmineで自動ログインができるとなれば、IISでWinodws認証をして、そのユーザ情報(REMOTE_USER)でRedmineに自動ログインしたくなります。

しかし、課題がありIISでリバースプロキシをするとうまくいきません。

本記事ではIISでリバースプロキシをするとうまくいかない理由を簡単に説明し、どのようにしたらその課題を打開できるのかを説明します。 具体的にはPHPでリバースプロキシ相当の処理をさせて課題を打開する方法を説明します。

IISのリバースプロキシ設定ではバックエンドにREMOTE_USERが送れない!?

本題の前に導入部分で触れた課題について説明します。

前提知識

IISではWinodws認証ができます。IISでWindows認証を設定すると認証に成功したユーザのみがWebページにアクセスできるようになります。 (Basic認証に馴染みがある方は、Basic認証のようなものだと思っておいてよいです。)

IISで認証をしているので、REMOTE_USER環境変数も設定されます。 (IISでFastCGIを動かすと、スクリプトからREMOTE_USERを参照することができます。)

IISでリバースプロキシ設定をしたときの課題

ということで、IISでWindows認証を有効にするとREMOTE_USERが設定されるので、「IISでリバースプロキシ」)の通り「ARR」と「URL 書き換え」を使ってリバースプロキシを設定したら、バックエンドにもREMOTE_USERを転送してほしいところですが、そうはなりません。

これは「URL 書き換え」がREMOTE_USERの値が設定される前に動作するためです。「URL 書き換え」が動作するタイミングではREMOTE_USERの値がないので、バックエンドに転送もできないというわけです。

課題の打開方法

いくつか方法はあると思いますが、今回はPHPでリバースプロキシを実現する方法を紹介します。

理由は以下の2つです。(小難しく書きましたが、要は一番簡単に実現できそうだったからです。)

  1. IISでFastCGIを動かすと、スクリプトからREMOTE_USERを参照するのは容易
  2. PHPでリバースプロキシを実装しているスクリプトがすでにあった

「Windows認証でRedmineに自動ログイン」: 設定手順

本題の「Windows認証でRedmineに自動ログイン」の設定方法を説明します。 /redmine というパスで運用する設定例です。 またRedmineの静的ファイルはIISが返すように設定をします。

やること

  1. 準備: IISでPHPを動かす設定
  2. 準備: アプリケーションの追加
  3. 準備: IISでWindows認証を有効にする
  4. 準備: PHPのハンドラーマッピングの設定
  5. Redmine関連の設定もろもろ
  6. no.php の配置と設定
    • = リバースプロキシの設定
  7. IISでURL書き換え設定

準備の1~4については一般的な設定なので、つまづきそうなポイントを中心に簡単な説明のみに留めます。

準備の1~4

すべて表示すると長すぎてメリハリがないので準備の1~4は非表示にしています。ご覧になりたい場合は「詳細」から確認をお願いします。

1. 準備: IISでPHPを動かす設定

IISでPHPを動かすためには「IISにFastCGIをインストール」と「PHPのインストール」を行う必要があります。

IISにFastCGIをインストール

Microsoftのドキュメントの通りに「サーバー マネージャー」で「CGI」をインストールします。 ドキュメントの通りにポチポチ押してインストールするだけなのでスムーズにインストールできると思います。

CGIの追加: https://learn.microsoft.com/ja-jp/iis/configuration/system.webserver/fastcgi/#setup

PHPのインストール

ダウンロードページ( https://www.php.net/downloads )からZIPファイルをダウンロードして展開するだけです。

ダウンロードして展開するだけではありますが、いくつかポイントがあるので紹介します。

  • ダウンロードページに「Windows downloads」というWindows専用のページがあるのでそこからダウンロードする
    • Non Thread SafeのZIPファイルをダウンロード
  • 展開すると php-cgi.exe というファイルがあるはずなのでダブルクリックをしてみる

2. 準備: アプリケーションの追加

「Default Web Site」へ設定する例です。 サイト > Default Web Site で右クリックをして表示されるメニューの「アプリケーションの追加」から追加します。

/redmine というパスで運用するので、次の通り設定します。

  • エイリアス
    • redmine
  • 物理パス
    • C:\inetpub\wwwroot\redmine
    • リバースプロキシを実現するPHPスクリプトを配置するので、IISのドキュメントルート以下に設定

(「IISでリバースプロキシ > A. パスごとにアプリケーションを追加する方法」にも説明があります。)

3. 準備: IISでWindows認証を有効にする

IISで「Windows認証」をするためには「Windows認証のインストール」と「Windows認証の有効化」を行う必要があります。

Windows認証のインストール

Microsoftのドキュメントの通りに「サーバー マネージャー」で「Winodws Authentication」をインストールします。 ドキュメントの通りにポチポチ押してインストールするだけなのでスムーズにインストールできると思います。

Winodws Authenticationの追加: https://learn.microsoft.com/ja-jp/iis/configuration/system.webserver/security/authentication/windowsauthentication/#setup

Windows認証の有効化

「Windows認証」を設定する範囲は選ぶことができます。今回はURLの /redmine パス以下にのみ設定したいので、redmine アプリケーションにて設定します。

redmine アプリケーションを開くと「認証」というアイコンがあるのでダブルクリックしてメニューを開きます。 そして「Windows認証」のみ有効にします。「Windows認証」以外は無効にしてください。

Windows 認証を有効にする方法: https://learn.microsoft.com/ja-jp/iis/configuration/system.webserver/security/authentication/windowsauthentication/#how-to-enable-windows-authentication-for-a-web-site-web-application-or-web-service

4. 準備: PHPのハンドラーマッピングの設定

今回は redmine アプリケーションでのみ有効になるように設定するので、redmine アプリケーションの「ハンドラー マッピング」をダブルクリックします。

右のメニューにある「モジュール マップの追加」をクリックして「モジュールマップの編集」画面で設定します。

スクリーンショット:モジュールマップ

  • 要求パス
    • *.php
  • モジュール
    • FastCgiModule
  • 実行可能ファイル
    • C:\PHP\php-cgi.exe
      • この例では C:\PHP\ へPHPをインストールしたのでこのパスですが適宜環境に合わせて設定してください
    • php.exeではなく、php-cgi.exeの方を選ぶ
    • 選択画面でファイルの種類が *.dll になっていると*.exeは表示されないので変更して選ぶ
    • 適宜PHPをインストールしたパスに変更してください
  • 名前
    • PHPなり、PHP-FastCGI なり、わかりやすい名前を設定

PHP 用のグローバル FastCGI ハンドラー マッピングを作成する方法: https://learn.microsoft.com/ja-jp/iis/configuration/system.webserver/fastcgi/#how-to-create-a-global-fastcgi-handler-mapping-for-php

5. Redmine関連の設定もろもろ

やること

  • Redmine Plugin Auth Remote Userを導入
  • Redmineを起動
  • Redmineの静的ファイルを物理パスにコピー

Redmine Plugin Auth Remote Userを導入

REMOTE_USERを使ってRedmineで自動ログイン」でも紹介している通りにインストールと設定をします。概要のみ記載します。

プラグインのインストール

Redmineのフォルダに移動し、プラグインをcloneします。

cd redmine
git clone https://gitlab.com/redmine-plugin-auth-remote-user/redmine-plugin-auth-remote-user.git plugins/auth_remote_user
REMOTE_USERの置換設定

「Windows認証」の場合、REMOTE_USER には domain\username のように domain\ 付きで設定されるので、「domain\usernameからdomain\の部分のみ削除」を有効にして domain\ を削除します。

注意:

  • Redmine Plugin Auth Remote Userの仕様上、REMOTE_USERにRedmineのログインIDが含まれていないと自動ログインはできません
  • 置換設定を誤ると予期せぬログインが発生するリスクがありますので、機能を理解した上、入念な検証をした後にご利用ください
Redmineを起動

/redmine というパスで運用するための設定をして起動します。

set SCRIPT_NAME=/redmine
set RAILS_RELATIVE_URL_ROOT=/redmine
ruby bin/rails server
  • SCRIPT_NAME

    • 生成されるリンクのパスに SCRIPT_NAME で指定したパスが付与されます
  • RAILS_RELATIVE_URL_ROOT

    • 静的ファイルのパスに RAILS_RELATIVE_URL_ROOT で指定したパスが付与されます
Redmineの静的ファイルを物理パスにコピー

Redmineフォルダにはpublic/というフォルダがあります。そこにスタイルシートや画像など静的ファイルが配置されています。 そのフォルダの中身を物理パスにコピーします。

この記事ではアプリケーションの物理パスを C:\inetpub\wwwroot\redmine に設定したので、そのフォルダにコピーします。 public/javascripts/ であれば、C:\inetpub\wwwroot\redmine\javascripts\* のように配置します。 (物理パスは適宜置き換えてコピーしてください。)

6. no.php の配置と設定

https://raw.githubusercontent.com/abetomo/no.php/refs/heads/patch-clear-code/no.php をダウンロードして、C:\inetpub\wwwroot\redmine\index.php に配置します。(配置するフォルダはアプリケーションの設定に合わせて変更してください。ファイル名もお好みで変更してください。)

no.php について: 本家の方だと一部機能が不足しているので、機能追加のプルリクエストを出しました。2024/09/25現在取り込まれていないため、上記のフォークリポジトリからダウンロードしてください。)

no.php はスクリプト内で設定をするため、配置した後に直接変更をして環境に合った設定をします。

設定例:

-$backend_url = "https://myapp.backend.com:3000/";
+$backend_url = "http://localhost:3000";
 $backend_info = parse_url($backend_url);
 $host = $_SERVER['HTTP_HOST'];
 $request_uri = $_SERVER['REQUEST_URI'];
-$uri_rel = "subdir/no.php"; # URI to this file relative to public_html
-$is_followlocation = true;
+$uri_rel = "/redmine"; # URI to this file relative to public_html
+$is_followlocation = false;

-$request_includes_nophp_uri = true;
+$request_includes_nophp_uri = false;
 if ( $request_includes_nophp_uri == false) {
  • $backend_url
    • バックエンドののURLを指定します
    • ローカルで動いているRedmineをしているする場合は http://localhost:3000 を指定します
  • $uri_rel
    • 運用するパスを指定します
    • /redmine で運用するので /redmine を指定します
    • 次のセクションで説明する「IISでURL書き換え設定 > /redmine へのアクセスを index.php へのアクセスに書き換え」と連動しているので合わせて設定してください
  • $is_followlocation
    • バックエンドのリダイレクト処理をそのそのままブラウザに返すかどうか
    • false にするとそのままブラウザに返します
    • Redmineではログインに成功するとマイページにリダイレクトされます。それを正しく扱うために false を設定します
  • $request_includes_nophp_uri = false
    • バックエンドにリクエストするときに $uri_rel を含めるかどうか
    • 今回は含まないURLを受け付けるようにRedmineを起動するので false にします

7. IISでURL書き換え設定

/redmine パスについて設定したいので、redmine アプリケーションの「URL 書き換え」で設定します。 具体的には /redmine へのアクセスを index.php へのアクセスに書き換える設定をします。

この設定がいないと/redmine/index.php/projects/redmine/index.php/issuesのようにパスにindex.phpが含まれてしまいカッコよくありません。 自然なパスで利用できるように設定します。

「URL 書き換え」画面の右のメニューから「規則の追加」をクリックします。

スクリーンショット:規則の追加

「規則の追加」メニューが開きますので、規則テンプレートの中から「空の規則」をダブルクリックします。

スクリーンショット:規則の追加

表示される「受信規則の編集」で以下の通り設定をします。

スクリーンショット:index.phpへのrewrite設定

  • 名前
    • 例では rewrite-to-index.php を設定しましたが適宜わかりやすい名前を設定してください
  • パターン
    • (.*)
  • 条件
    • 条件の設定で静的ファイルはIISが返すを実現します
    • 「追加」で条件追加のメニューを開き、「入力文字列が次の条件を満たしているかどうかチェック」の選択肢から「ファイルではない」を選んで「OK」を押します。そうするとキャプチャの通り設定されます
    • この設定でドキュメントルートに静的ファイルがある場合はそれをIISが返し、ないときはindex.phpへのアクセスへ書き換える、が実現できます
  • URLの書き換え
    • index.php/{R:1}
    • {R:1}でパターンの(.*)にマッチした部分を参照します
  • 後続の規則の処理を処理を停止する
    • チェックする

この設定で /redmine/projects というリクエストは /redmine/index.php/projects というリクエストに内部で書き換えられます。

(「条件」の効果で /redmine/javascripts/tribute-5.1.3.min.js といったドキュメントルートにある静的ファイルはIISが直接返します。)

おまけ: no.php でバランサ

ApacheでリバースプロキシをしてRedmineを運用する場合、Apacheモジュールのmod_proxy_balancerを利用する場合があります。

参考: https://httpd.apache.org/docs/2.4/ja/mod/mod_proxy_balancer.html

WindowsではRedmineがマルチプロセスで動きません。 そこでRedmineのサーバを複数起動し、Apacheでロードバランスをする構成をとることがあります。 それと同等の設定を no.php で実現するための設定例を紹介します。

Redmineの起動:

ポート番号3001、3002、3003、3004の4つのサーバを起動します。(コマンド例はイメージです)

set SCRIPT_NAME=/redmine
set RAILS_RELATIVE_URL_ROOT=/redmine
ruby bin/rails server --port 3001 --pid tmp/pids/3001.pid
ruby bin/rails server --port 3002 --pid tmp/pids/3002.pid
ruby bin/rails server --port 3003 --pid tmp/pids/3003.pid
ruby bin/rails server --port 3004 --pid tmp/pids/3004.pid

no.php の設定:

$backend_url の設定がポイントなので、そこの差分だけ記載します。

-$backend_url = "https://myapp.backend.com:3000/";
+$backend_urls = [
+    "http://localhost:3001",
+    "http://localhost:3002",
+    "http://localhost:3003",
+    "http://localhost:3004",
+];
+$backend_url = $backend_urls[array_rand($backend_urls, 1)];

バックエンドのURLを配列で定義して、その中からランダムで1つ選ぶ、という設定です。

まとめ

「Windows認証でRedmineに自動ログイン」の設定方法を紹介しました。

IISでリバースプロキシを実現するよくある方法(「ARR」と「URL 書き換え」を使ってリバースプロキシ)で実現できれは単純な話だったのですが、実現できなかったため、PHPでリバースプロキシを実現しました。