PHPでシングルサインオン(SSO)を使う方法【現役エンジニアが解説】

PROGRAM

今回は、PHPでシングルサインオン(SSO)を使う方法について、ライブラリ側とアプリケーション側の設定に分け、簡単に解説していきます。

PHPでのシングルサインオン(SSO)のライブラリ側の設定

PHPでシングルサインオンを使う場合には、php-samlというライブラリを使います。

ここでGitHubライブラリを利用する理由は、独自でシングルサインオンを実装するにはOASIS標準のSAMLについての学習が必要となり大変な手間がかかるからです。

シングルサインオンは認証サーバ側の設定にも依存してライブラリの設定も変わってきますが、ここではミニマムの構成を想定して、まずはライブラリのsettings.phpを書き変えます。

    $spBaseUrl = "http://<your_domain>"; // アプリケーション側のベースURL
    $idpBaseUrl = "http://<server_domain>"; // 認証サーバ側のベースURL
    $spAcsUrl = $spBaseUrl . "<acs_api>"; // SSO戻り値対応用のURL(ACS)
    $idpSsoUrl = $idpBaseUrl . "<sso_api>"; // 認証サーバ側のSSO対応用URL
    $idpEntityId = "<idp_entityId>"; // アプリケーションを特定する認証サーバ側の識別文字
    
    $settingsInfo = array(
    	'strict' => false,
    	'debug' => true,
        'sp' => array(
            'entityId' => $spBaseUrl,
            'assertionConsumerService' => array(
                'url' => $spAcsUrl,
            ),
            'NameIDFormat' => 'urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified',
        ),
        'idp' => array(
            'entityId' => $idpEntityId,
            'singleSignOnService' => array(
                'url' => $idpSsoUrl,
            ),
            'x509cert' => ''
        ),
    );

その他に関しては、php-samlディレクトリ内にxmlseclibsフォルダがない場合には、php-samlで必要となってきますので、xmlseclibsよりダウンロードしてphp-samlディレクトリ内に配置し、必要に応じて_toolkit_loader.phpのxmlseclibsのパスを書き変えておきましょう。

PHPでのシングルサインオン(SSO)のアプリケーション側の設定

ライブラリ側の設定は認証サーバ側に依存しますが、アプリケーション側はその点自由です。

まず、ログインする入り口のプログラムに関してはシンプルに以下のコードだけで事足ります。

use OneLogin\Saml2\Auth;
use OneLogin\Saml2\Utils;
session_start();
$phpSamlPath = "<php_saml_path>";
require_once $phpSamlPath.'_toolkit_loader.php';
equire_once $phpSamlPath.'settings.php';	
$auth = new Auth($settingsInfo);

$auth->login();

次に、シングルサインオンの認証サーバ側から戻って来た際に対応するプログラム(ACS)は、以下のようなコードになります。

use OneLogin\Saml2\Auth;
use OneLogin\Saml2\Utils;
session_start();
$phpSamlPath = "<php_saml_path>";
require_once $phpSamlPath.'_toolkit_loader.php';
equire_once $phpSamlPath.'settings.php';	
$auth = new Auth($settingsInfo);

if ( isset($_POST['SAMLResponse']) ) {
    if (isset($_SESSION) && isset($_SESSION['AuthNRequestID'])) {
        $requestID = $_SESSION['AuthNRequestID'];
    } else {
        $requestID = null;
    }
    $auth->processResponse($requestID);				
    $errors = $auth->getErrors();
    if (!empty($errors)) {echo(implode(', ', $errors));}
    if ($auth->isAuthenticated()) {
        $attributes = $auth->getAttributes();
        $NameId = $auth->getNameId();
        unset($_SESSION['AuthNRequestID']);

        // 取得した$NameIdを使って権限マスタの参照やセッション変数への値の格納を行う
        
    } else {
        echo ( $auth->getLastErrorReason() );
    }
}

認証サーバ側の設定によって多少異なりますが、多くの場合には、このサンプルコードで言うところの$NameIdにユーザを識別するコードが入っていることが多いので、これを利用してアプリケーション側で自由にログイン処理を行う形となります。

シングルサインオンの実情

中小企業でシングルサインオンを使っている企業は稀であると思いますが、大手企業ではシングルサインオンを使うところは多いです。

その理由は、アプリケーションごとにログインすることが煩雑ということもさることながら、中央の統合認証サーバで一括でユーザ、そしてその権限の管理ができるからです。

ここで紹介した方法はフェデレーション方式と呼ばれる連携方法となり、認証サーバと同一ネットワーク内に属さないSalesforce等のクラウドサービスでも利用することができる便利なシングルサインオンの方式になります。

シングルサインオンは、開発者にノウハウがないとなかなか実装は難しいと言われていますが、実際にはphp-samlのように便利なライブラリが無償で提供されていますので、ドキュメントをきちんと読めば誰でも実装が可能となります。