🍈

Apache + Laravel で構成するSAML認証環境を検証してみる

2022/07/19に公開

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 --from=composer:latest /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,
>   ]
> ],   

検証

  1. http://sp1.local:8080/ でアクセスし、SP の mod_auth_mellon で指定したロケーションにおける SAML認証 が行われるかをテスト
  2. http://idp.local:18080/login にリダイレクトされ、ログインを行うことができる
  3. ログイン直後は IdP のダッシュボードに遷移
  4. 再度、 SP にアクセス
  5. http://sp1.local:8080/mellon/postResponce で 400 エラーにならない
  6. アクセスしたURLのまま、 SP のページが表示される
  7. $_SERVERMELLON_ から始まる環境変数が設定され、 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.phpquery_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 導入 (その参)

Mellon Cookie が付与できない旨のQ&A文献

mod_auth_mellon を使用したSAML認証のドキュメント(成り立ちから検証方法の例までが書かれているので、実装目線からの全体把握に役立ちます)

Discussion