Apache + Laravel で構成するSAML認証環境を検証してみる
mod_auth_mellon による SAML 認証
2022年7月時点で、全く文献が無く苦労した経験から作業ログを残すことにします汗
とはいえ、走り書きで残したログでもあるので、抜け漏れについてはご容赦ください汗
SSO を導入する機会があり、その採用候補としてあがったSAML認証の動作検証を行いました。認証を行うためのユーザー情報を、Laravel Authを中心とする構成としたかったところもあり、Apache + Laravel の環境構成を組んでみています。
前提
構成概要
- M1 Mac Dockerコンテナで検証
- SP(Service Provider)はApache + PHPコンテナ(※ 環境変数を見たいためPHPも入れました)
- IdP(Identity Provider)もApache + PHPコンテナで、Laravelをインストール
- SPにはApacheの拡張モジュール「
mod_auth_mellon
」を採用 - IdPにはLaravelのパッケージ
codegreencreative/laravel-samlidp
を採用
検証環境
ディレクトリ構成概要
※ PHPファイルも置いていますが、環境変数を見たかっただけなので、認証処理本体に関わるファイルではないです。
docker-compose.yml
version: '3.9'
services:
sp-app-1:
image: php:8.1-apache
container_name: lara-sp1
volumes:
- type: bind
source: ./sp1/app
target: /var/www/html
ports:
- 8080:80
sp-app-2:
image: php:8.1-apache
container_name: lara-sp2
volumes:
- type: bind
source: ./sp2/app
target: /var/www/html
ports:
- 8081:80
idp-app:
container_name: lara-idp
build:
context: .
dockerfile: ./idp/Dockerfile
volumes:
- type: bind
source: ./idp/app
target: /var/www/html
ports:
- 18080:80
IdPのDockerfile
FROM php:8.1-apache
RUN apt update \
&& apt install -y \
vim \
g++ \
libicu-dev \
libpq-dev \
libzip-dev \
zip \
zlib1g-dev
COPY /usr/bin/composer /usr/bin/composer
ENV COMPOSER_ALLOW_SUPERUSER 1
ENV COMPOSER_HOME /composer
ENV PATH $PATH:/composer/vendor/bin
WORKDIR /var/www/html
RUN composer global require "laravel/installer"
SP1コンテナ(lara-sp1)立ち上げ後に行うコマンド
※ 本来は Dockerfile
に記載しておくべきと思いますが、検証段階だったため、手動で実施しています。
# パッケージインストール
apt-get update
apt-get install -y vim libapache2-mod-auth-mellon wget
apt-get clean
# apacheの設定
a2enmod auth_mellon
a2enmod headers
# mod_auth_mellon の設定
mkdir /etc/apache2/saml
cd /etc/apache2/saml
wget https://raw.githubusercontent.com/latchset/mod_auth_mellon/master/mellon_create_metadata.sh
chmod +x mellon_create_metadata.sh
# コンテナを抜けて設定反映
exit
$ docker-compose restart
IdPコンテナ(lara-idp)立ち上げ後に行うコマンド
※ 本来は Dockerfile
に記載しておくべき以下略
# Document Root を /var/www/html/public に変更
vi /etc/apache2/sites-available/000-default.conf
# codegreencreative/laravel-samlidp でPHPの
# ショートコードエラーが発生するので、ショートコード機能をOFFにする
vi /usr/local/etc/php/php.ini
# mod_rewrite を ON
a2enmod rewrite
# コンテナを抜けて設定反映
exit
$ docker-compose restart
実装
IdPの環境用意
codegreencreative/laravel-samlidp
の Readme のまんまです。
GitHub - codegreencreative/laravel-samlidp: Laravel SAML IdP
Laravel をインストール済み、かつ、 Laravel Auth
をセットアップ済み、の状況を前提とします。
# IdPパッケージをインストール
composer require codegreencreative/laravel-samlidp
# config配下に設定ファイルをパブリッシュ
php artisan vendor:publish --tag="samlidp_config"
# SAMLリクエスト解析前の鍵交換・複合化をするため、鍵ファイルを作成する
# 鍵ファイルを設置するディレクトリを設定
vi config/filesystem.php
# 鍵ファイルを作成(所有者情報の入力をおこなうが、空Enterで進んでも検証は可)
# 実行完了後、storage配下に鍵ファイルが設置される
php artisan samlidp:cert
# SPをクライアントとして登録する。laravel-samlidp ではハッシュ化した
# ACS URLをキーにクライアント認証を行っているので、それを生成するコマンドを実行する
# - 1つ目の問合せでは「ACS URL(destination)」を入力
# - 2つ目の問合せではログアウトURL(logout)を入力
# 出力結果 config/samlidp.php の sp プロパティとして設定
php artisan samlidp:sp
vi config/samlidp.php
> 'sp' => [
> 'aHR0cHM6L .... cGhw' => [
> 'destination' => 'http://sp1.local:8080/mellon/postResponse',
> 'logout' => 'http://sp1.local:8080/mellon/logout',
> ]
> ],
IdPのメタデータを取得
インストール直後、何もなければ /saml/metadata
でSAML認証で利用するメタデータXMLが取得できます。SP側に設定するメタデータに使用するので、取得をしておいた方が良いです。
http://idp.local:18080/saml/metadata
SPでメタデータを生成
wget
でダウンロードしておいたメタデータ生成プログラム「 mellon_create_metadata.sh
」でSP側のメタデータを作成します。
これによって、SP/IdP間のSAML認証における暗号化・複合化ができるので、やっておきましょう。
# 実行ファイルがある場所に行って、コマンドを実行
# 証明書、秘密鍵、公開鍵、メタデータXMLが生成されます
cd /etc/apache2/saml/
./mellon_create_metadata.sh sp1 http://sp1.local:8080/mellon
# 生成した各種ファイルを使ってSAMLリクエスト/レスポンスを行えるようにします
# SP側は mod_auth_mellon が担うので、その設定ファイルに記入します
vi /etc/apache2/mods_available/auth_mellon.conf
> <Location />
> AuthType "Mellon"
> Require valid-user
> MellonEnable "auth"
> MellonEndpointPath "/mellon"
> MellonIdPMetadataFile /etc/apache2/saml/idp-metadata.xml
> MellonSPPrivateKeyFile /etc/apache2/saml/sp1.key
> MellonSPCertFile /etc/apache2/saml/sp1.cert
> MellonSPMetadataFile /etc/apache2/saml/sp1.xml
> MellonSecureCookie On
> MellonCookieSameSite None
> </Location>
IdPのメタデータを設置
mod_auth_mellon
で IdP のメタデータを利用するためXML形式で設置します。
vi /etc/apache2/saml/idp-metadata.xml
SPのメタデータ内の証明書データを取得しておく
IdP には複合のための証明書データが必要になるので、メタデータ内の証明書文字列を取得しておく。
cat /etc/apache2/saml/sp1.xml
> <X509Certificate> {{ ここの中身を抽出しておく }} </X509Certificate>
IdPに証明書を入力
先に抽出した証明書文字列を config/samlidp.php
に SP に対応する証明書として指定しておきます。
vi config/samlidp.php
> 'sp' => [
> 'aHR0cHM6L .... cGhw' => [
> 'destination' => 'http://sp1.local:8080/mellon/postResponse',
> 'logout' => 'http://sp1.local:8080/mellon/logout',
> 'certificate' => "MIIDrzCCAhc ..... 2j1cwh9Ks=",
> 'query_params' => false,
> ]
> ],
検証
-
http://sp1.local:8080/ でアクセスし、SP の
mod_auth_mellon
で指定したロケーションにおける SAML認証 が行われるかをテスト - http://idp.local:18080/login にリダイレクトされ、ログインを行うことができる
- ログイン直後は IdP のダッシュボードに遷移
- 再度、 SP にアクセス
- http://sp1.local:8080/mellon/postResponce で 400 エラーにならない
- アクセスしたURLのまま、 SP のページが表示される
-
$_SERVER
にMELLON_
から始まる環境変数が設定され、SAML Response
から変数化されていることが確認できる
Error Resolve
/mellon/postResponce が 400 エラーになる
- Apacheのエラーログ(/var/log/httpd/error_log もしくは Docker のコンテナログ)のメッセージを確認してみてください。
- SP側の Cookie が許可されていない可能性があるので、
mod_auth_mellon
の「MellonSecureCookie
」と「MellonCookieSameSite
」の設定を確認してみてください。 - SP と IdP でドメインや
ACS URL
が不一致の可能性があります。GET パラメータ付きでも不一致と認識されるので、メタデータXMLやconfig/samlidp.php
のquery_params
の指定を確認してみてください。 - Cookie に「
saml-cookie=cookietest
」というようなレコードがあるならば、削除して再度検証してみてください。これは Session 生成途中の段階で発生するもののようで、認証が完了していないことも表します。検証にはノイズでしかないので、設定見直しのうえ、再度検証する場合には注意が必要です。
文献
mod_auth_mellon を使ってみた - Qiita
SAML SPをつくろう 【mod_auth_mellon編】 | 株式会社セシオス
【IT備忘録】 Apache2 への mod_auth_mellon 導入 (その壱)
【IT備忘録】 Apache2 への mod_auth_mellon 導入 (その弐)
【IT備忘録】 Apache2 への mod_auth_mellon 導入 (その参)
mod_auth_mellon を使用したSAML認証のドキュメント(成り立ちから検証方法の例までが書かれているので、実装目線からの全体把握に役立ちます)
Discussion