SAML認証
Azure AD を IdPとして利用する設定
Azure AD の設定。
Azure AD はフリープランでOK.
参考
ユーザを追加する
SAML設定自体とは関係ないが、前準備として、ユーザを追加する。
ユーザー → 新しいユーザ → 新しいユーザの作成
- ユーザープリンシパル名: 任意のユーザ名@xxxoutlook.onmicrosoft.com
- 表示名
- パスワード(自動生成)
IdPを作成する
エンタープライズアプリケーション → 新しいアプリケーション → 独自のアプリケーションの作成
- お使いのアプリケーション名: 任意の名前
- ギャラリーに見つからないその他のアプリケーションを統合します (ギャラリー以外)
ユーザーの追加
ユーザーとグループ → ユーザまたはグループの追加 → ユーザ
→ 追加したいユーザをチェックして、選択
シングルサインオンの設定
シングルサインオン
→ シングルサインオン方式
- SAML
→ 基本的なSAML構成
- 識別子: エンティティ ID
- 応答 URL: AssertionConsumerService
- ログアウト URL: SingleLogoutService
(SP側で作成したメタデータをアップロードすることでも設定可能なようだ)
→ SAML証明書
- フェデレーション メタデータ XMLをダウンロード → SP 側に保存する。
サインインログ
アクティビティ → サインインログで確認できる。
Apache mod_auth_mellon で SAML SP の設定
参考
環境
ここでは Docker コンテナ内に構築します。
$ sudo docker run --rm -it -p 443:443 -v /home/pi/work/test/mellon:/opt --name mellontest debian:bullseye-slim bash
パッケージの導入
動作に必要なパッケージを導入します。
# apt update
# apt install --no-install-recommends apache2 libapache2-mod-auth-mellon openssl
IdP メタデータ作成
mellon_create_metadata の第一引数は Entityid 、第二引数は endpoint 。
作成したらリネームしておく。
# mkdir -p /etc/apache2/mellon
# cd /etc/apache2/mellon
# /usr/sbin/mellon_create_metadata https://test.example.com/ "https://test.example.com/mellon"
# mv *.key mellon.key
# mv *.cert mellon.cert
# mv *.xml mellon_metadata.xml
SP メタデータ mellon_metadata.xml を IdPに登録する。
mod_auth_mellon の設定ファイルを作成
IdPから取得したメタデータを /etc/apache2/mellon/IdP_metadata.xml に配置する。
<location />
MellonSPPrivateKeyFile /etc/apache2/mellon/mellon.key
MellonSPCertFile /etc/apache2/mellon/mellon.cert
MellonSPMetadataFile /etc/apache2/mellon/mellon_metadata.xml
MellonIdPMetadataFile /etc/apache2/mellon/IdP_metadata.xml
MellonEndpointPath /mellon
MellonEnable "auth"
</Location>
TLS接続するための証明書を作成
ここでは自己署名のオレオレ証明書を作成している。
コモンネームはよしなに。
# openssl req -newkey rsa:3072 -new -x509 -days 3652 -nodes -out /etc/ssl/certs/mywebserver.pem -keyout /etc/ssl/private/mywebserver.key -subj '/C=JP/ST=Tokyo/L=Shinjuku/CN=コモンネーム'
Apache 設定ファイルを作成
Apache の設定ファイルを作成する。
ServerName サーバ名
<IfModule mod_ssl.c>
<VirtualHost _default_:443>
DocumentRoot /var/www/html
ServerSignature Off
ErrorLog /var/log/apache2/error.log
CustomLog /var/log/apache2/access.log combined
LogLevel info ssl:warn
SSLEngine on
SSLCertificateFile /etc/ssl/certs/mywebserver.pem
SSLCertificateKeyFile /etc/ssl/private/mywebserver.key
</VirtualHost>
<Location /protected>
Require valid-user
AuthType "Mellon"
MellonEnable "auth"
MellonDecoder "none"
MellonVariable "cookie"
MellonSecureCookie On
MellonUser "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
</Location>
</IfModule>
SAML認証によって守られるべきテストコンテンツを作成
# mkdir -p /var/www/html/protected
# date > /var/www/html/protected/index.html
設定を有効化
# apache2ctl configtest
# a2enmod ssl
# a2enconf mellon.conf
# a2ensite mywebserver.conf
# a2dissite 000-default.conf
# apache2ctl graceful
Docker 化に向けて
作成したApache 設定ファイルを Docker ホストへコピーしておく
sudo docker copy mellontest:/etc/apache2 .
今後作成するDockerイメージからは、Apache 設定ファイル、SSL 証明書、Web コンテンツをマウントして利用する想定。
Docker で SimpleSAMLphp を動かす
SimpleSAMLphp のバージョンは 2.0.5 を利用します。
参考
Docker イメージを作成
下記のような内容で Dockerfile を作成する
まっさらの alpine のイメージから作ろうと試行錯誤したのだが、php-openssl を入れたところで、nginx/error.log への php のログ出力が無くなってしまい作業が進まなくなった。
なので、 php:8.1-fpm-alpine を利用することにした。
(ベストプラクティス的には nginx は別イメージにするべきかもしれない)
FROM php:8.1-fpm-alpine
RUN apk update \
&& apk add nginx \
&& rm -rf /var/cache/apk/*
VOLUME ["/var/www/html", "/etc/nginx/http.d"]
EXPOSE 443
CMD php-fpm -D && nginx -g 'daemon off;'
イメージを作成
$ sudo docker build --build-arg http_proxy=http://<プロキシアドレス>:<プロキシポート>/ -f Dockerfile -t nginx-php-fpm:test .
nginx の設定ファイルを作成
作業ディレクトリに nginx の設定ファイルを作成
server {
listen 443 ssl default_server;
server_name idp.example.com;
ssl_certificate /etc/pki/tls/certs/example.org.crt;
ssl_certificate_key /etc/pki/tls/private/example.org.pem;
ssl_protocols TLSv1.3 TLSv1.2;
ssl_ciphers EECDH+AESGCM:EDH+AESGCM;
location ^~ /simplesaml {
alias /var/simplesamlphp/public;
location ~^(?<prefix>/simplesaml)(?<phpfile>.+?\.php)(?<pathinfo>/.*)?$ {
include fastcgi_params;
fastcgi_pass localhost:9000;
fastcgi_param SCRIPT_FILENAME $document_root$phpfile;
# Must be prepended with the baseurlpath
fastcgi_param SCRIPT_NAME /simplesaml$phpfile;
fastcgi_param PATH_INFO $pathinfo if_not_empty;
}
}
}
TLS接続用のサーバ証明書を作成する。
コモンネームはよしなに。
$ openssl req -newkey rsa:3072 -new -x509 -days 3652 -nodes -out example.org.crt -keyout example.org.pem -subj '/C=JP/ST=Tokyo/L=Shinjuku/CN=コモンネーム'
SimpleSAMLphp の準備
公式からダウンロードしてきたアーカイブを展開する
$ curl -L https://github.com/simplesamlphp/simplesamlphp/releases/download/v2.0.5/simplesamlphp-2.0.5.tar.gz -o simplesamlphp-2.0.5.tar.gz
$ tar xzvf simplesamlphp-2.0.5.tar.gz
$ simplesamlphp-2.0.5.tar.gz
Docker 起動
$ sudo docker run --name simplesaml --rm -d -p 8443:443 \
-v <作業ディレクトリパス>/simplesamlphp-2.0.5:/var/simplesamlphp \
-v <作業ディレクトリパス>/http.d:/etc/nginx/http.d \
-v <作業ディレクトリパス>/example.org.crt:/etc/pki/tls/certs/example.org.crt \
-v <作業ディレクトリパス>/example.org.pem:/etc/pki/tls/certs/example.org.pem \
nginx-php-fpm:test
SimpleSAMLphp を IdP として設定
ネット上の日本語情報はVer1系のものが多かったが、Ver2系の設定を進めるうえでは、あまり参考にならなかった。
参考
設定
simplesamlphp-2.0.5 ディレクトリ内で下記を変更
証明書作成
openssl req -newkey rsa:3072 -new -x509 -days 3652 -nodes -out cert/example.org.crt -keyout cert/example.org.pem -subj '/C=JP/ST=Tokyo/L=Shinjuku/CN=コモンネーム'
ソルト値作成
LC_ALL=C tr -c -d '0123456789abcdefghijklmnopqrstuvwxyz' </dev/urandom | dd bs=32 count=1 2>/dev/null;echo
パスワードハッシュ作成
$ sudo docker exec -it simplesaml php -f /var/simplesamlphp/bin/pwgen.php
Enter password: password1234
$2y$10$PWH6KnnQPmLkchR7xcuPmercvnxQ/NowObU65KHdkJNHfRmyY7vWS
$ cp -pi config/config.php{,.dist}
$ vi config/config.php
以下を変更
'baseurlpath' => 'https://yourfqdn:port/simplesaml/',
'secretsalt' => '作成したソルト値',
'auth.adminpassword' => '作成したパスワードハッシュ',
'enable.saml20-idp' => true,
'exampleauth' => true,
$ cp -pi config/authsources.php{,.dist}
$ vi config/authsources.php
以下を変更
'entityID' => 'エンティティID',
コメントアウトされている 'example-userpass' => [], の箇所の有効化
$ cp -pi metadata/saml20-idp-hosted.php{,.dist}
$ vi metadata/saml20-idp-hosted.php
$metadata['エンティティID']
'privatekey' => '作成した秘密鍵',
'certificate' => '作成した証明書',
https://yourfqdn:port/simplesaml/ で表紙画面が表示できる。
管理画面は https://yourfqdn:port/simplesaml/admin/ で表示できる。
設定したパスワードで中に入れる。
連携ページのツール「XMLをSimpleSAMLphpメタデータに変換」を開く
SPメタデータの内容を貼り付けてパースをクリック。
$ cp -pi metadata/saml20-sp-remote.php{,.dist}
$ vi metadata/saml20-sp-remote.php
上でパースされた内容に置き換える。
SimpleSAMLphp を SP として設定
参考
設定
simplesamlphp-2.0.5 ディレクトリ内で下記を変更
ソルト値作成
パスワードハッシュ作成
confit.php 編集
$ cp -pi config/config.php{.dist,}
'baseurlpath' => 'https://yourfqdn:port/simplesaml/',
'secretsalt' => '作成したソルト値',
'auth.adminpassword' => '作成したパスワードハッシュ',
authsources.php 編集
$ cp -pi config/authsources.php{.dist,}
$ vi config/authsources.php
以下を変更
'entityID' => 'エンティティID',
saml20-idp-remote.php の編集
$ cp -pi metadata/saml20-idp-remote.php{.dist,}
$metadata['https://example.org/saml-idp'] = [
'SingleSignOnService' => 'https://example.org/simplesaml/saml2/idp/SSOService.php',
'SingleLogoutService' => 'https://example.org/simplesaml/saml2/idp/SingleLogoutService.php',
'certificate' => 'example.pem',
];
https://yourfqdn:port/simplesaml/ で表紙画面が表示できる。
管理画面は https://yourfqdn:port/simplesaml/admin/ で表示できる。
設定したパスワードで中に入れる。
連携ページの Hosted entities の SAML 2.0 SP metadata の メタデータの内容(XML形式)を、IdP側でインポートする。
IdP側のメタデータをエクスポート
連携ページのツール「XMLをSimpleSAMLphpメタデータに変換」を開く
IdPメタデータの内容を貼り付けてパースをクリック。
$ vi metadata/saml20-idp-remote.php
上でパースされた内容を追記する。
テスト
Testページで、SP名をクリックすると、IdPの認証画面へ推移する。
認証が成功すると、ステータスページが表示され、属性情報、認証データなどを確認できる。