PHPのSAML認証でログインできないときの切り分け:Microsoft Entra IDとonelogin/php-samlを確認する
作成日:2026.08.23
PHPのonelogin/php-samlとMicrosoft Entra IDを組み合わせたSAML認証で、ログインできない原因を切り分ける方法を解説します。Microsoft Entra IDのエラー情報とSAML Chrome Panelで確認したSAMLRequest・SAMLResponseをもとに、Entity ID、ACS URL、Audience、Recipient、Destination、署名証明書、時刻条件、NameID・クレームなどを確認します。
目次
PHPでSAML認証を実装していると、Microsoft Entra IDのログイン画面までは表示されるものの、認証後にアプリケーションへ戻れなかったり、戻った後に検証エラーになったりすることがあります。
今回は、Microsoft Entra IDをIdP(Identity Provider)、onelogin/php-samlを利用したPHPアプリケーションをSP(Service Provider)として、SAML認証に失敗したときの切り分け方法を整理します。
SPの構築手順やonelogin/php-samlの基本的な実装そのものではなく、Microsoft Entra ID側、SAMLメッセージ、PHPアプリケーション側のどこに問題があるのかを分けて確認することが目的です。
前提
今回の構成は次の通りです。
- PHPアプリケーション
onelogin/php-saml- Microsoft Entra IDをIdPとして利用
- PHPアプリケーションをSAMLのSPとして利用
- 単独のPHPアプリケーションを例にする
以前、onelogin/php-samlを使ってPHPでSAML認証を実装する例を紹介しました。今回はそのようなSPがすでに用意され、Microsoft Entra IDとの認証フローを開始できる状態から確認します。
まず認証のどこで失敗しているかを分ける
SAML認証は、SPからIdPへ認証要求を送信し、IdPで認証した後、IdPからSPのACS(Assertion Consumer Service)へSAMLResponseを返す流れで動作します。
PHPアプリケーション(SP)
↓ SAMLRequest
Microsoft Entra ID(IdP)
↓ SAMLResponse
PHPアプリケーションのACS
↓
ユーザーセッションを作成
最初に、次のどの状態なのかを確認します。
| 状態 | 主に確認する場所 |
|---|---|
| Microsoft Entra IDへ移動する前に失敗する | PHPの設定、Composer、SAMLRequestの生成処理 |
| Microsoft Entra IDの画面でエラーになる | Microsoft Entra IDのエラー、SAMLRequest、エンタープライズアプリケーションの設定 |
| 認証後にACSへ戻らない | ACS URL、Reply URL、リダイレクト、HTTPS、ネットワーク |
| ACSへ戻った後にエラーになる | SAMLResponse、証明書、Audience、Recipient、時刻、onelogin/php-samlの検証結果 |
| 認証は成功するがユーザー情報を取得できない | NameID、クレーム、属性名、PHPアプリケーションのセッション処理 |
Microsoft Entra IDのログイン画面で失敗しているのか、Microsoft Entra IDはSAMLResponseを返しているもののPHPアプリケーションが受け付けていないのかで、確認する場所が変わります。
SAMLRequestとSAMLResponseを確認する
設定ファイルだけを見ていると、実際に送信されたURLや値との違いを見落とすことがあります。ブラウザで認証を実行し、SAMLRequestとSAMLResponseの内容を確認します。
SAML Chrome Panelを使う
今回は、確認事項で指定したSAML Chrome Panelを利用します。SAML認証を実行した後、ChromeのデベロッパーツールからSAMLRequestとSAMLResponseの内容を確認します。
過去の記事でもSAML Chrome Panelを紹介していますが、拡張機能の画面や配布状況は変わる可能性があります。利用できない場合は、Microsoftが案内しているMy Apps Secure Sign-in Extensionや、開発環境で利用できる通信確認ツールを検討します。
確認したSAMLメッセージには、ユーザー識別子、メールアドレス、テナント情報、署名情報などが含まれる場合があります。実際のSAMLRequestやSAMLResponseを、オンラインのデコードサービスへ貼り付けないようにしてください。
Microsoftの公式手順でも、SAMLのテスト時にエラーメッセージ、SAMLRequest、SAMLResponseを確認し、Issuer、Destination、AssertionConsumerServiceURL、NameID、クレーム、署名証明書を確認する流れが説明されています。
Microsoft Entra ID側のテストを使う
Microsoft Entra管理センターで、対象のエンタープライズアプリケーションを開きます。
- 「エンタープライズ アプリケーション」から対象アプリケーションを開く。
- 「シングル サインオン」を開く。
- 認証方式として「SAML」を選択する。
- 「SAML ベースのサインオンをテストする」から認証を実行する。
エラーが表示された場合は、エラーコードだけでなく、画面に表示されるCorrelation ID、Request ID、Timestampも控えます。これらはMicrosoft Entra側のログを検索したり、問い合わせたりするときに利用します。
Microsoft Entra IDとPHP側の設定を比較する
Microsoft Entra IDの「基本的なSAML構成」と、onelogin/php-samlの設定ファイルを、同じ項目ごとに比較します。
| 確認項目 | Microsoft Entra ID側 | onelogin/php-saml側 |
|---|---|---|
| SPの識別子 | 識別子(Entity ID) | sp.entityId |
| ACS | 応答URL(Assertion Consumer Service URL) | sp.assertionConsumerService.url |
| IdPの識別子 | フェデレーションメタデータのEntity ID | idp.entityId |
| SSO URL | ログインURLまたはメタデータのSSOエンドポイント | idp.singleSignOnService.url |
| 署名証明書 | SAML署名証明書 | idp.x509cert |
設定値の比較では、URLのホスト名だけでなく、スキーム、パス、末尾のスラッシュ、ポート番号まで確認します。例えば、次の2つは見た目が似ていますが、別のURLです。
https://example.test/saml/acs
https://example.test/saml/acs/
Microsoft Entra IDの識別子と、SPがSAMLRequestのIssuerへ設定する値が一致しているかも確認します。Microsoftの公式手順では、Issuerはアプリケーションに設定した識別子と一致し、AssertionConsumerServiceURLはSAMLトークンを受け取るアプリケーションのURLであることを確認するよう案内されています。
SAMLRequestを確認する
Microsoft Entra IDのログイン画面でエラーになる場合は、Microsoft Entra IDへ送信したSAMLRequestを確認します。HTTP-Redirectバインディングでは、SAMLRequestがURLのクエリパラメーターとして送信されます。
デコードしたXMLでは、少なくとも次の項目を確認します。
Issuer: Microsoft Entra IDの「識別子」と一致しているかDestination: Microsoft Entra IDのSSO URLになっているかAssertionConsumerServiceURL: PHPアプリケーションのACS URLになっているかProtocolBinding: ACS側で受け付けるバインディングと一致しているかID: リクエストごとに生成されているかIssueInstant: 現在時刻から大きくずれていないかNameIDPolicy: Microsoft Entra ID側の設定と矛盾していないか
例えば、Microsoft Entra IDから「SAMLリクエストのDestinationが想定外」といったエラーが出る場合は、SAMLRequestのDestinationと、Microsoft Entra IDから取得したSSO URLを比較します。
Microsoft Entra IDの代表的なエラーコードには、SAMLメッセージのバインディングやDestination、認証要求の時刻に関するものがあります。
| エラーコードの例 | 確認する内容 |
|---|---|
AADSTS75001、AADSTS75003 |
SAMLメッセージのバインディングやシリアライズ |
AADSTS75005 |
Microsoft Entra IDが受け付けられないSAMLRequestになっていないか |
AADSTS75008 |
SAMLRequestのDestination |
AADSTS76026 |
SAML認証要求のIssueTimeと、SP側の時刻 |
AADSTS50011 |
返信先URL、つまりACS URLの設定 |
エラーコードやメッセージは変更される可能性があるため、コード番号だけをアプリケーションの判定条件にしないでください。Microsoftの最新のエラーコード一覧と、Microsoft Entra管理センターのエラー内容を確認します。
SAMLResponseを確認する
Microsoft Entra IDで認証した後にACSへ戻り、PHPアプリケーションの画面でエラーが表示される場合は、Microsoft Entra IDが発行したSAMLResponseを確認します。
SAMLResponseでは、次の項目を順に確認します。
ResponseのIssuerとStatus
Response/Issuerが想定したMicrosoft Entra IDのIssuerになっているかResponse/Status/StatusCodeが成功を示しているかInResponseToが、SPから送信した認証要求のIDと対応しているかDestinationが、実際にSAMLResponseを受信したACS URLになっているか
AssertionのAudienceと条件
Assertion/Issuerが想定したIdPになっているかAudienceRestriction/AudienceがSPのEntity IDになっているかNotBefore、NotOnOrAfterの範囲に現在時刻が含まれているかSubjectConfirmationData/RecipientがACS URLになっているかSubjectConfirmationData/InResponseToが認証要求のIDと一致しているか
認証要求のDestinationはIdPのSSO URLですが、SAMLResponseのDestinationはSPのACS URLです。同じ名前の項目でも、どのメッセージに含まれているかで確認する相手が変わるため注意してください。
署名証明書と属性
- Microsoft Entra IDがSAMLResponseまたはAssertionへ付けた署名を確認する。
- 署名に使われた証明書が、PHP側の
idp.x509certと一致しているか確認する。 NameIDの値と形式が、アプリケーションの想定と一致しているか確認する。- メールアドレスやユーザーIDなど、アプリケーションが必要とするクレームが含まれているか確認する。
Microsoft Entra IDのユーザー属性やクレームが不足している場合、Microsoft Entra ID側では認証が成功していても、アプリケーション側でユーザーを特定できないことがあります。
onelogin/php-samlのエラーを確認する
onelogin/php-samlでSAMLResponseを処理している部分では、processResponse()の後にgetErrors()とgetLastErrorReason()を確認します。
<?php
require __DIR__ . '/vendor/autoload.php';
session_start();
$settingsInfo = require __DIR__ . '/config/settings.php';
$auth = new OneLogin\Saml2\Auth($settingsInfo);
$auth->processResponse();
$errors = $auth->getErrors();
if (!empty($errors)) {
// 詳細なエラーは開発環境のログだけに出す。
error_log('[SAML] ' . implode(', ', $errors));
error_log('[SAML] ' . $auth->getLastErrorReason());
http_response_code(500);
echo 'SAML認証の応答を検証できませんでした。';
exit;
}
if (!$auth->isAuthenticated()) {
http_response_code(401);
echo '認証されていません。';
exit;
}
$attributes = $auth->getAttributes();
$_SESSION['samlUserdata'] = $attributes;
この処理でエラーが返った場合は、エラー文字列だけでなく、直前に取得したSAMLResponseの次の項目と照合します。
- AudienceとSPのEntity ID
- Recipient、Destination、ACS URL
- InResponseToと認証要求のID
- 署名証明書
- NotBefore、NotOnOrAfter
- NameIDと属性
エラーを画面へそのまま表示すると、設定値や内部パスなどを利用者へ公開する可能性があります。開発時の確認が終わったら、画面には一般的なエラーだけを表示し、詳細はアクセス制限したログで確認する構成にします。
設定ファイルのstrictと証明書を確認する
onelogin/php-samlの設定例では、strictを有効にすると、署名、Destination、NameID、Conditionsなどの検証が行われます。検証を緩めることでログインできるようにするのではなく、SAMLResponseと設定の不一致を解消することを優先します。
'strict' => true,
'debug' => false,
'sp' => [
'entityId' => 'https://sp.example.test/metadata.php',
'assertionConsumerService' => [
'url' => 'https://sp.example.test/acs.php',
'binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST',
],
],
本番環境でdebugを有効にしたままにしたり、検証を無効にしたりする設定は避けます。onelogin/php-samlの公式リポジトリでも、本番環境ではstrictを有効にし、SHA-1以外の署名アルゴリズムとダイジェストアルゴリズムを使用するよう案内されています。
IdPの署名証明書を指紋だけで管理している場合は、可能であれば証明書そのものを設定する方法も検討します。Microsoft Entra IDで署名証明書が更新された場合は、PHP側の証明書設定が古いままになっていないか確認してください。
原因別の切り分け
Entity IDまたはAudienceが一致しない
Microsoft Entra IDの「識別子」と、PHP側のsp.entityId、SAMLResponseのAudienceを比較します。
Entity IDはURL形式で設定することが多いものの、実際に比較するときはURLとして正規化されると決めつけず、文字列として値を確認します。末尾のスラッシュや大文字・小文字の違いも確認対象です。
ACS URL、Recipient、Destinationが一致しない
Microsoft Entra IDの応答URL、PHP側のsp.assertionConsumerService.url、SAMLResponseのDestinationとRecipientを比較します。
リバースプロキシやロードバランサーの内側でPHPが動作している場合、外部から見えるHTTPSのURLと、PHPが認識しているHTTPのURLが異なることがあります。SAMLに設定したURL、ブラウザのアドレスバーのURL、WebサーバーからPHPへ渡されるホスト・スキームを確認します。
証明書または署名が一致しない
Microsoft Entra IDのSAML署名証明書を更新した後は、PHP側のidp.x509certも更新します。証明書のPEM形式、改行、余分な文字列が原因になることもあるため、設定値を確認します。
証明書の更新前後でSAMLResponseに含まれる署名証明書が変わっていないかを比較すると、証明書の差し替え漏れを切り分けやすくなります。
時刻がずれている
SAMLResponseには、Assertionが有効な時間帯を示すNotBeforeやNotOnOrAfterが含まれます。PHPを実行しているサーバーの時刻が大きくずれていると、正しいSAMLResponseでも期限外として扱われることがあります。
PHPのタイムゾーン設定だけでなく、OSや仮想環境のシステム時刻も確認します。SAMLResponseの時刻と、エラーが発生した時刻を同じタイムゾーンへそろえて比較してください。
NameIDまたはクレームが不足している
Microsoft Entra ID側で送信するユーザー属性を変更した場合、SAMLResponseに含まれるNameIDやクレームも変わる可能性があります。
認証後のPHP処理で、次のように属性名を固定していないか確認します。
$attributes = $auth->getAttributes();
$email = $attributes['email'][0] ?? null;
if ($email === null) {
// Microsoft Entra ID側のクレーム名と一致しているか確認する
}
属性が存在しない場合は、PHPコードだけを変更するのではなく、Microsoft Entra IDの「属性とクレーム」で設定している名前、値、NameIDの形式を確認します。
ユーザー割り当てやポリシーで拒否されている
SAMLのURLや署名が正しくても、エンタープライズアプリケーションへユーザーまたはグループが割り当てられていない場合、ログインできないことがあります。
特定のユーザーだけが失敗する場合は、全体設定だけでなく、ユーザー割り当て、グループ、条件付きアクセス、ユーザーのテナントを確認します。
確認結果を記録する
設定を一度に複数変更すると、何が原因だったのか分からなくなります。次のような表を作り、確認した値と結果を記録します。
| 確認項目 | 確認元 | 結果 |
|---|---|---|
| SPのEntity ID | Entra ID / sp.entityId / SAMLRequestのIssuer |
一致・不一致 |
| ACS URL | Entra ID / sp.assertionConsumerService.url / SAMLResponseのRecipient |
一致・不一致 |
| 署名証明書 | Entra ID / SAMLResponse / idp.x509cert |
一致・不一致 |
| 時刻条件 | SAMLResponse / PHP実行環境 | 範囲内・範囲外 |
| NameID・クレーム | Entra ID / SAMLResponse / PHPコード | 取得可・取得不可 |
確認用にSAMLResponseを保存する場合は、元のファイルをそのまま共有用資料へ使わず、ユーザー識別子、メールアドレス、テナント情報、証明書、RelayStateなどをマスキングします。
まとめ
Microsoft Entra IDとonelogin/php-samlのSAML認証でログインできないときは、最初に失敗箇所を分類します。
Microsoft Entra IDの画面で失敗している場合は、エラー内容とSAMLRequestを確認し、Issuer、Destination、AssertionConsumerServiceURLを比較します。認証後にPHP側で失敗している場合は、SAMLResponseのAudience、Recipient、時刻条件、署名証明書、NameID、クレームを確認します。
onelogin/php-samlのgetErrors()とgetLastErrorReason()は切り分けの手掛かりになりますが、エラー文字列だけで原因を決めず、SAMLメッセージとMicrosoft Entra ID側の設定を照合することが重要です。
SAMLResponseには認証情報やユーザー属性が含まれる場合があるため、ログ出力や共有時は必要な情報だけを残し、開発用の詳細表示を本番環境へ持ち込まないようにしましょう。
参考資料
奈良市を拠点に、27年以上の経験を持つフリーランスWebエンジニア、阿部辰也です。
これまで、ECサイトのバックエンド開発や業務効率化システム、公共施設の予約システムなど、多彩なプロジェクトを手がけ、企業様や制作会社様のパートナーとして信頼を築いてまいりました。
【制作会社・企業様向けサポート】
Webシステムの開発やサイト改善でお困りの際は、どうぞお気軽にご相談ください。小さな疑問から大規模プロジェクトまで、最適なご提案を心を込めてさせていただきます。
ぜひ、プロフィールやWeb制作会社様向け業務案内、一般企業様向け業務案内もご覧くださいね。
Microsoft Entra IDの属性とクレームをPHPで取得する:SAMLResponseとonelogin/php-samlの対応方法
2026.08.29
Microsoft Entra IDの「属性とクレーム」で設定したユーザー属性を、SAMLResponseのNameIDやAttributeStatementで確認し、onelogin/php-samlのgetNameId()・getAttributes()でPHPから取得する方法を解説します。クレーム名とPHP側の配列キーが一致しない場合の確認ポイントも整理します。
onelogin/php-samlで実現するPHP SAML認証:基本設定から動作確認まで
2025.09.25
軽量ライブラリである onelogin/php-saml を利用して、PHPでSAML認証を実装する方法を詳しく解説します。Composerによるインストールから、証明書・秘密鍵の準備、設定ファイルの作成、そしてSPのメタデータ生成やSSO・ACSの各スクリプトまで、SAML認証の基本設定と動作確認の一連の流れをサンプルコードを交えて紹介。
SimpleSAMLphpを使ったPHPアプリケーションのSSO対応ガイド
2025.02.11
SimpleSAMLphpを使ってPHPアプリケーションにSSO機能を追加する方法を紹介します。Microsoft Entra IDとの連携方法や、認証情報の取得方法について詳しく解説します。
Microsoft Entra IDとSimpleSAMLphpを利用したSAML認証SSO構築ガイド
2025.01.26
ローカル環境でMicrosoft Entra IDと連携したSAML認証のシングルサインオンを実現するための手順を紹介します。SimpleSAMLphpを利用した設定方法や、Microsoft側の構成変更について詳しく解説しています。