今回は完全プライベートなネタではないのですが、
Cakephp3を使ってSAML認証を行うプラグインを作成したのでその使い方をまとめようと思います。
(SAMLの設定が結構面倒なのでまとめておきたかったってのもあります。)
■環境構築
何はともあれ、まずは環境構築です。
今回の構成は以下のようになります。
・基盤
OS: CentOS7.2
Webサーバー:Apache2.4
PHP: 5.6
・アプリケーション
Identity Provider: SimpleSAMLphp
Service Provider: Cakephp3.x + 自前プラグイン(SamlAuthenticationPlugin)
●Apacheインストール
# yum install httpd
●PHP5.6インストール
普通にyumでインストールすると5.4系が入るため、
ここを参考にEPELとRemiリポジトリのパッケージを使用します。
# yum install epel-release
# rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
# yum install --enablerepo=remi,remi-php56 php php-devel php-mbstring php-mysql php-pdo php-gd php-xml php-mcrypt php-gmp php-intl
バージョンを確認してみましょう。
# php -v
PHP 5.6.31 (cli) (built: Jul 6 2017 08:06:11)
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
Cakephpのパッケージ管理に使用されているためComposerをインストールします。
# curl -sS https://getcomposer.org/installer | php
# mv composer.phar /usr/local/bin/composer
●SimpleSAMLphp配置
SimpleSAMLphpを配置します。配置先はhttp://xxx.xxx.xxx/simplesaml/とします。
まずは、公式サイトからファイルを落としてきましょう。
DLし終わったらSCPなどを使ってWebサーバーにアップロードしてください。
●SimpleSAMLphpの設定
ファイルの解凍と配置を行います。(私は/var/www/simplesaml/に配置しました)
# tar zxvf simplesamlphp-1.14.16.tar.gz
# mv simplesamlphp-1.14.16 /var/www/simplesaml
●Cakephp3.x + 自前プラグイン
まずはCakephpを配置します。(私は/var/www/ssoapp/に配置しました)
# composer self-update && composer create-project --prefer-dist cakephp/app ssoapp
pluginsフォルダにSAML認証プラグインを配置します。
# cd ssoapp/plugins
# git clone https://github.com/gittrname/SamlAuthenticationPlugin.git
プラグインを有効化しましょう。
# cd ..
# vi config/bootstrap.php
// 最下部に追記
Plugin::load('SamlAuthenticationPlugin', ['bootstrap' => true, 'routes' => true]);
# vi composer.json
// 以下を編集
"josegonzalez/dotenv": "2.*"
↓
"josegonzalez/dotenv": "2.*",
"onelogin/php-saml": "^2.11.0"
"psr-4": {
"App\\": "src"
}
↓
"psr-4": {
"App\\": "src",
"SamlAuthenticationPlugin\\": "plugins/SamlAuthenticationPlugin/src"
}
終わったらcomposerで外部ライブラリのインストールと
autoloadの構築を行います。
# composer install
●ApacheのAlias設定
# vi /etc/httpd/conf.d/saml.conf ← 新規作成
// 以下を記載
Alias /simplesaml/ /var/www/simplesaml/www/
<Directory /var/www/simplesaml/www/>
AllowOverride None
Require all granted
</Directory>
Alias /ssoapp/ /var/www/ssoapp/webroot/
<Directory /var/www/ssoapp/webroot/>
AllowOverride None
Require all granted
<IfModule mod_rewrite.c>
RewriteEngine On
# RewriteRule ^(.*)/$ /ssoapp/$1 [L,R=300]
RewriteBase /ssoapp
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
</Directory>
Apacheを再起動します。
# systemctl restart httpd
ここまででとりあえず前段階終了です。
・・・・そう!前段階なんです。この後の設定が回りくどく苦戦しました;;;
ざっくり行くと、まずIdpの証明書情報などをSPに登録、
次にSPの証明書情報などをIdpに登録する流れになります。
●Idpの証明書情報をSPに登録
登録する前にIdp側で証明書を作成します。
(実働環境だとオレオレではなく正規に発行してもらったものを使用するんでしょうね)
# cd /var/www/simplesaml/cert
# openssl req -newkey rsa:2048 -new -x509 -days 3652 -nodes -out server.crt -keyout server.pem
SAML2.0-Idpのモジュールを有効化します。
# vi /var/www/simplesaml/config/config.php
// 以下を変更
'enable.saml20-idp' => false,
↓
'enable.saml20-idp' => true,
# touch modules/exampleauth/enable
終わったらhttp://xxx.xxx.xxx/simplesaml/saml2/idp/metadata.phpにアクセスしてみましょう。
XMLが表示されたらその内容をメモっておきます。
必要となるのは「md:EntityDescriptorのentityId」「ds:X509Certificateの証明書文字列」
「md:SingleLogoutServiceのLocation」「md:SingleSignOnServiceのLocation」です。
では、SPに登録しましょう。
・・・・・とその前にSPの証明書を作成します;;;(またかよ・・・)
これも実働環境だと(ry
# cd /var/www/ssoapp/plugins
# mkdir cert
# cd cert
# openssl req -newkey rsa:2048 -new -x509 -days 3652 -nodes -out server.crt -keyout server.pem
作成した証明書をプラグインに設定します。
# cd ..
# cd config
# vi app.php
<?php
return [
'saml_config' => [
'baseurl' => 'http://xxx.xxx.xxx/ssoapp',
'sp' => [
'entityId' => 'http://xxx.xxx.xxx/ssoapp',
'assertionConsumerService' => [
'url' => 'http://xxx.xxx.xxx/ssoapp/saml-auth/login',
],
'singleLogoutService' => [
'url' => 'http://xxx.xxx.xxx/ssoapp/saml-auth/logout',
],
'NameIDFormat' => 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress',
'x509cert' => '{server.crtの中身をコピペ}',
'privateKey' => '{server.pemの中身をコピペ}'
],
'idp' => [
'entityId' => 'md:EntityDescriptorのentityId',
'singleSignOnService' => [
'url' => '{md:SingleSignOnServiceのLocation}',
],
'singleLogoutService' => [
'url' => '{md:SingleLogoutServiceのLocation}',
],
'x509cert' => '{ds:X509Certificateの証明書文字列}'],
]
];
保存したらhttp://xxx.xxx.xxx/ssoapp/saml-auth/metadataを表示してみてください。
XMLが表示されたらOKです。例によってこのXMLの情報をIdp設定で使用します。
●SPの証明書情報をIdpに登録
# vi /var/www/simplasaml/metadata/saml20-sp-remote.php
// 以下を追記
$metadata['http://xxx.xxx.xxx/ssoapp/'] = array(
'AssertionConsumerService' => 'http://xxx.xxx.xxx/ssoapp/saml-auth/login',
'SingleLogoutService' => 'http://xxx.xxx.xxx/ssoapp/saml-auth/logout',
'NameIDFormat' => 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress',
'simplesaml.nameidattribute' => 'uid',
'simplesaml.attributes' => FALSE,
);
認証用アカウント(ID=test, Pass=test)を作成
# vi /var/www/simplasaml/config/authsources.php
<?php
$config = array(
'example-userpass' => array(
'exampleauth:UserPass',
'test:test' => array(
'uid' => array('test'),
'eduPersonAffiliation' => array('member', 'employee'),
),
),
これで完了です。
■動作確認
http://xxx.xxx.xxx/loginにアクセスするとIdp側のログイン画面にリダイレクトされます。
そこで認証が完了すればSP側に戻って認証情報が参照できるはずです。
・動作サンプル
参考)