Skip to content

証明書のインポート(OS・環境別) ​

第6版作成 最終更新 (日本時間)
対応バージョンPleasanter 1.4 以降確認バージョン1.5.8.1

SAML 認証や LDAP(LDAPS)連携では、IdP やディレクトリサーバーの証明書をプリザンターの動作環境にインポートする必要があります。SAML の IdP 署名証明書は、プリザンター(.NET)が Authentication.json で指定された X509Store の中から探すので、.NET の X509Store から見えるストアに入れるのがポイントです。OS の CA トラストストアに追加しても、この検索には使われません。

  • Windows は GUI・PowerShell・certutil のいずれかで個人ストア(My)にインポートします。
  • Linux は、プリザンターの実行ユーザーで PowerShell 7 から X509Store.Add を呼び、.NET の CurrentUser\My(実行ユーザーのホームの ~/.dotnet/corefx/cryptography/x509stores/my/)にインポートします。LocalMachine は使えません。update-ca-certificates や NSS の certutil では CurrentUser\My に入りません。
  • Docker は、ストアが実行ユーザーのホームにできるため、PowerShell 入りの .NET SDK イメージで作ったストアをイメージに焼き込むか、ボリュームで渡します。
  • Azure App Service は、Windows プランなら WEBSITE_LOAD_CERTIFICATES の設定で CurrentUser\My から読めます。Linux プランは証明書がファイルとして置かれるだけなので、カスタムコンテナーで Docker と同じ手順にします。AWS / Google Cloud はコンテナなら Docker、VM なら Linux と同じ手順です。

INFO

プリザンター 1.4 系以降が対象です。SAML 認証の設定手順そのものは 認証(Google Workspace の SAML SSO / SMTP の OAuth) を参照してください。以下の URL・拇印・ファイルパス・ユーザー名はすべてダミー値です。

証明書が参照される仕組み ​

SAML 認証では、Authentication.json の IdentityProviders の SigningCertificate で証明書の検索条件を指定します。FindValue などは IdentityProviders の直下ではなく SigningCertificate の中に書きます(既定の Authentication.json)。

json
"IdentityProviders": [
    {
        "EntityId": "https://idp.example.com/...",
        "SignOnUrl": "https://idp.example.com/sso",
        "SigningCertificate": {
            "StoreName": "My",
            "StoreLocation": "CurrentUser",
            "X509FindType": "FindByThumbprint",
            "FindValue": "A1B2C3D4E5F6..."
        }
    }
]
項目(SigningCertificate の中)説明
FindValue証明書の拇印(Thumbprint / Fingerprint)
X509FindType検索方法。拇印で探すなら FindByThumbprint(既定)
StoreLocationCurrentUser または LocalMachine(既定は CurrentUser)。Linux では CurrentUser だけが使える(後述)
StoreName証明書ストア名(通常は My。既定も My)

プリザンターは StoreName と StoreLocation で X509Store を開き(OpenFlags.OpenExistingOnly)、X509FindType と FindValue で検索して、見つかった最初の証明書を IdP の署名検証用の鍵として登録します(Saml.cs)。ソースから読み取れるのは次の点です。

  • 証明書ファイルのパスを指定する項目はなく、X509Store の中しか探しません。
  • 検索は Find(..., validOnly: false) なので、見つけるときに証明書チェーンや信頼の検証はしません。IdP の自己署名証明書でもそのまま見つかります。
  • OpenExistingOnly で開くため、指定したストアが存在しないと例外になります。
  • SigningCertificate を書かない場合(IdP のメタデータを読み込む構成など)は、ストアを参照しません(if (paramIdp.SigningCertificate != null))。

図を読み込み中…

拇印の確認方法 ​

FindValue に設定する拇印は、環境を問わず次のコマンドで確認できます。

bash
# SHA-1 拇印を確認
openssl x509 -in certificate.pem -fingerprint -sha1 -noout
# 出力例: SHA1 Fingerprint=A1:B2:C3:D4:E5:F6:...

コロンを除いて FindValue にそのまま使える形で取り出すには次のようにします。

bash
openssl x509 -in certificate.pem -fingerprint -sha1 -noout | sed 's/SHA1 Fingerprint=//;s/://g'

Windows では PowerShell でも確認できます。

powershell
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("certificate.pem")
$cert.Thumbprint

Windows ​

GUI(証明書のインポートウィザード) ​

  1. .pem または .cer ファイルをダブルクリックし、「証明書のインポートウィザード」を開きます。
  2. 保存場所を選択します。
    • CurrentUser:「現在のユーザー」
    • LocalMachine:「ローカル コンピューター」(IIS でホストする場合はこちらを推奨)
  3. 証明書ストアは「個人」(My)を選択します。
  4. インポート後、証明書の管理画面を開いて拇印をコピーします。
    • CurrentUser の場合:certmgr.msc
    • LocalMachine の場合:certlm.msc

PowerShell ​

powershell
# LocalMachine の個人ストアにインポート
Import-Certificate -FilePath "C:\certs\idp-certificate.pem" -CertStoreLocation Cert:\LocalMachine\My

# CurrentUser の個人ストアにインポート
Import-Certificate -FilePath "C:\certs\idp-certificate.pem" -CertStoreLocation Cert:\CurrentUser\My

インポート後の拇印は次のように確認します。

powershell
# LocalMachine の個人ストアの証明書一覧を表示
Get-ChildItem Cert:\LocalMachine\My | Format-Table Subject, Thumbprint

certutil ​

cmd
:: LocalMachine の個人ストアにインポート
certutil -addstore My "C:\certs\idp-certificate.pem"

:: CurrentUser の個人ストアにインポート
certutil -user -addstore My "C:\certs\idp-certificate.pem"

INFO

certutil -addstore / -user -addstore は Windows の certutil の書式です。Linux の certutil(NSS のツール)は別物で、この書式は使えません。

Authentication.json の設定例(IIS) ​

json
"IdentityProviders": [
    {
        "EntityId": "https://idp.example.com/...",
        "SignOnUrl": "https://idp.example.com/sso",
        "SigningCertificate": {
            "StoreName": "My",
            "StoreLocation": "LocalMachine",
            "X509FindType": "FindByThumbprint",
            "FindValue": "A1B2C3D4E5F6..."
        }
    }
]

INFO

IIS でホストしている場合は、StoreLocation に LocalMachine を指定し、IIS のアプリケーションプール ID に証明書の読み取り権限を付与してください。

Linux ​

Linux では、プリザンターの実行ユーザーで、.NET の CurrentUser\My ストアに証明書を追加するのが唯一の手順です。Authentication.json は StoreLocation を CurrentUser、StoreName を My にします。OS の CA トラストストアへの追加は、SigningCertificate の検索には関係しません(必要になる場面は後述)。

.NET の X509Store は Linux でどこを見るか ​

Microsoft Learn の「.NET でのクロスプラットフォーム暗号化」によると、Windows 以外の X509Store は「システムの信頼の決定(読み取り専用)、ユーザー信頼の決定(読み取り/書き込み)、ユーザー キー ストレージ(読み取り/書き込み)のプロジェクション」で、Windows の証明書ストアとは仕組みが違います。プリザンターに関係するストアは次のとおりです。

ストアLinux での実体と挙動出典
CurrentUser\My実行ユーザーのホームの ~/.dotnet/corefx/cryptography/x509stores/my/ に、SHA-1 拇印をファイル名にして保存される。読み書きできる。既定では存在せず、最初の書き込みで作られるため、それまでは ExistingOnly で開くと失敗するクロスプラットフォーム暗号化、ASP.NET Core で HTTPS を適用する
LocalMachine\My開けない(CryptographicException がスローされる)クロスプラットフォーム暗号化
LocalMachine\RootOpenSSL の既定のパスにある CA バンドルを解釈したもの(読み取り専用)。update-ca-certificates などで更新されるのはこちらクロスプラットフォーム暗号化

NSS のデータベース(~/.pki/nssdb)は、X509Store の投影先として挙げられていません。NSS の certutil(libnss3-tools などのパッケージ)は、Microsoft Learn でも「ブラウザーの証明書ストアを管理する」ツールとして扱われています(ASP.NET Core で HTTPS を適用する)。

これとプリザンターのソース(Saml.cs)を合わせると、Linux では次のようになります。

  • StoreLocation に LocalMachine を指定すると、ストアを開く時点で例外になります。CurrentUser 以外は使えません。
  • 証明書を 1 件も追加していないユーザーでは CurrentUser\My がまだ存在しないので、OpenExistingOnly で開けずに例外になります。
  • CurrentUser はプリザンターのプロセスを動かしているユーザーです。root でインポートしても、別ユーザーで動くプリザンターからは見えません。
  • update-ca-certificates / update-ca-trust で更新されるのは LocalMachine\Root 側で、NSS の certutil は NSS のデータベースに書き込むだけなので、どちらも CurrentUser\My には入りません。

手順 ​

  1. PowerShell 7(pwsh)をインストールします。ディストリビューションごとの入手方法は対応表を参照してください。pwsh は .NET 上で動くので、pwsh から X509Store.Add を呼ぶと、プリザンターと同じ .NET のストアに書き込めます。

  2. 証明書ファイルを、プリザンターの実行ユーザーが読める場所に置きます。

    bash
    sudo install -d -m 755 /etc/pleasanter/certs
    sudo install -m 644 idp-certificate.pem /etc/pleasanter/certs/idp-certificate.pem
  3. プリザンターの実行ユーザーを確認します。systemd で動かしている場合は、ユニットの User= を見ます(空なら root)。

    bash
    systemctl show -p User pleasanter.service
    # 出力例: User=pleasanter
  4. 次のスクリプトを置き、プリザンターの実行ユーザーで実行します。sudo -H でホームディレクトリを実行ユーザーのものに切り替えるのが大事です(ストアは $HOME の下に作られます)。

    powershell
    param(
        [string]$Path = '/etc/pleasanter/certs/idp-certificate.pem'
    )
    $cert  = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new($Path)
    $store = [System.Security.Cryptography.X509Certificates.X509Store]::new(
        [System.Security.Cryptography.X509Certificates.StoreName]::My,
        [System.Security.Cryptography.X509Certificates.StoreLocation]::CurrentUser)
    # ReadWrite で開くと、ストアが無ければここで作られる
    $store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
    try {
        $store.Add($cert)
    }
    finally {
        $store.Close()
    }
    # FindValue に設定する拇印を表示
    $cert.Thumbprint
    bash
    sudo -u pleasanter -H pwsh -NoProfile -File /etc/pleasanter/certs/import-idp-cert.ps1 \
      -Path /etc/pleasanter/certs/idp-certificate.pem
  5. 実行ユーザーから見えることを確認します。

    bash
    # ストアのファイル(拇印.pfx)ができていること
    sudo -u pleasanter -H sh -c 'ls -la "$HOME/.dotnet/corefx/cryptography/x509stores/my/"'
    
    # .NET から見える証明書の一覧
    sudo -u pleasanter -H pwsh -NoProfile -Command '$s = [System.Security.Cryptography.X509Certificates.X509Store]::new("My", "CurrentUser"); $s.Open("ReadOnly"); $s.Certificates | Format-Table Subject, Thumbprint; $s.Close()'
  6. Authentication.json の SigningCertificate を次のように設定し、プリザンターを再起動します。

json
"IdentityProviders": [
    {
        "EntityId": "https://idp.example.com/...",
        "SignOnUrl": "https://idp.example.com/sso",
        "SigningCertificate": {
            "StoreName": "My",
            "StoreLocation": "CurrentUser",
            "X509FindType": "FindByThumbprint",
            "FindValue": "A1B2C3D4E5F6..."
        }
    }
]

WARNING

systemd のユニットで ProtectHome= を有効にしていたり、実行ユーザーのホームディレクトリが存在しなかったりすると、プリザンターから ~/.dotnet/corefx/cryptography/x509stores/ を読めません。インポートしたのに見つからないときは、ユニットの設定と実行ユーザーのホームを確認してください。

TIP

サーバーに PowerShell を入れたくない場合は、Docker と同じく、PowerShell 入りの .NET SDK コンテナで作ったストアのディレクトリ(x509stores)を、実行ユーザーのホームの ~/.dotnet/corefx/cryptography/x509stores/ にコピーする方法もあります。ディレクトリの所有者は実行ユーザーにしてください。

ディストリビューション別の対応表 ​

CurrentUser\My へのインポートに必要なのは PowerShell 7 だけです。CA トラストストアの配置先と更新コマンドは、CA トラストストアに追加する必要がある場合だけ使います。

項目Debian / UbuntuRHEL / CentOS / AlmaLinux / Rocky LinuxSUSE / openSUSEAlpine
PowerShell 7 の入手Microsoft のパッケージリポジトリから apt(Ubuntu / Debian)Microsoft のパッケージリポジトリから dnf(RHEL)Microsoft のサポート対象外。Snap や tar.gz で導入(コミュニティ サポート)tar.gz から導入(Alpine)
CA 証明書の配置先/usr/local/share/ca-certificates//etc/pki/ca-trust/source/anchors//usr/share/pki/trust/anchors//usr/local/share/ca-certificates/
CA 証明書の推奨拡張子.crt.pem.pem.crt
CA トラストストアの更新コマンドupdate-ca-certificatesupdate-ca-trustupdate-ca-certificatesupdate-ca-certificates
パッケージマネージャaptdnf / yumzypperapk

各ディストリビューションの対応状況は「Linux 用の PowerShell のサポート」を参照してください。.NET SDK が入っている環境なら dotnet tool install --global PowerShell でも入ります(PowerShell をインストールする別の方法)。

OS の CA トラストストアに追加する場合 ​

OS の CA トラストストアに追加すると、.NET からは LocalMachine\Root として見えます(クロスプラットフォーム暗号化)。前述のとおり、SigningCertificate は CurrentUser\My で探し、見つけるときに信頼の検証もしないので、IdP の署名証明書をここに追加する必要はありません。

追加が必要なのは、プリザンターから HTTPS や LDAPS で接続する相手(IdP のメタデータの URL、LDAP サーバーなど)のサーバー証明書をプライベート CA が発行していて、その CA を OS に信頼させたい場合です。そのときは、対応表の配置先に CA の証明書を置いて更新コマンドを実行します。

bash
# Debian / Ubuntu / Alpine(拡張子は .crt)
sudo cp private-ca.pem /usr/local/share/ca-certificates/private-ca.crt
sudo update-ca-certificates

# RHEL / CentOS / AlmaLinux / Rocky Linux
sudo cp private-ca.pem /etc/pki/ca-trust/source/anchors/private-ca.pem
sudo update-ca-trust

# SUSE / openSUSE
sudo cp private-ca.pem /usr/share/pki/trust/anchors/private-ca.pem
sudo update-ca-certificates

Docker ​

CurrentUser\My はコンテナの実行ユーザーのホームの下(root なら /root/.dotnet/corefx/cryptography/x509stores/)にできます。本体リポジトリの Dockerfile は USER を指定していないので、そのイメージのプリザンターは root で動きます(Dockerfile)。

起動中のコンテナの中でインポートしても、コンテナを作り直すと消えます。また、実行用の mcr.microsoft.com/dotnet/aspnet イメージには PowerShell が入っていません(PowerShell が入っているのは .NET SDK のイメージだけです。Docker での PowerShell の使用)。そのため、次のどちらかにします。

  • SDK イメージでストアを作り、プリザンターのイメージにコピーする(マルチステージビルド)
  • SDK コンテナでホスト側にストアを作り、ボリュームでマウントする

どちらも、Linux の手順の import-idp-cert.ps1 を使います。

マルチステージビルドでイメージに焼き込む ​

dockerfile
# 1. PowerShell が入っている .NET SDK イメージで、.NET の証明書ストアを作る
#    (プリザンターと同じ .NET のメジャーバージョンのイメージを使う)
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS certstore
COPY import-idp-cert.ps1 idp-certificate.pem /tmp/
RUN pwsh -NoProfile -File /tmp/import-idp-cert.ps1 -Path /tmp/idp-certificate.pem

# 2. プリザンターのイメージに、ストアのディレクトリだけをコピーする
#    (pleasanter-base は、本体リポジトリの Dockerfile でビルドしたイメージなどに置き換える)
FROM pleasanter-base:latest
COPY --from=certstore /root/.dotnet/corefx/cryptography/x509stores/ /root/.dotnet/corefx/cryptography/x509stores/

USER で root 以外のユーザーに切り替えているイメージでは、そのユーザーのホームへ所有者を付けてコピーします。

dockerfile
COPY --from=certstore --chown=app:app /root/.dotnet/corefx/cryptography/x509stores/ /home/app/.dotnet/corefx/cryptography/x509stores/
USER app

ビルド後に、コンテナからストアが見えることを確認します。

bash
docker exec pleasanter sh -c 'ls -la "$HOME/.dotnet/corefx/cryptography/x509stores/my/"'

docker-compose でボリュームをマウントする ​

証明書を差し替えるたびにイメージを作り直したくない場合は、SDK コンテナでホスト側にストアを作り、プリザンターのコンテナにマウントします。ストアをボリュームに置くので、コンテナを作り直しても残ります。

bash
# ./certs に idp-certificate.pem と import-idp-cert.ps1 を置いてから実行する
docker run --rm \
  -v "$PWD/certs:/certs:ro" \
  -v "$PWD/x509stores:/root/.dotnet/corefx/cryptography/x509stores" \
  mcr.microsoft.com/dotnet/sdk:10.0 \
  pwsh -NoProfile -File /certs/import-idp-cert.ps1 -Path /certs/idp-certificate.pem
yaml
services:
  pleasanter:
    image: pleasanter-base:latest
    volumes:
      # コンテナの実行ユーザー(ここでは root)のホームの下にマウントする
      - ./x509stores:/root/.dotnet/corefx/cryptography/x509stores

WARNING

証明書ファイル(.pem)をコンテナにマウントするだけでは、プリザンターは読みません。プリザンターが探すのは X509Store の中だけです(Saml.cs)。また、Dockerfile やエントリポイントで update-ca-certificates や NSS の certutil を実行しても、CurrentUser\My には入りません。

Azure App Service ​

  1. Azure ポータルで対象の App Service を開きます。
  2. 「証明書」メニューを開き、「公開キー証明書 (.cer) の追加」をクリックします。
  3. 名前に任意の識別名(例: idp-certificate)を入力し、証明書ファイルをアップロードします。
  4. 一覧に表示された拇印(Thumbprint)をコピーします。
  5. 「構成」→「アプリケーション設定」で WEBSITE_LOAD_CERTIFICATES に拇印を設定します(すべての証明書を読み込む場合は *)。
  6. 設定を保存し、App Service を再起動します。

WEBSITE_LOAD_CERTIFICATES で証明書がどこに読み込まれるかは、プランによって違います(アプリケーション コードで TLS/SSL 証明書を使用する)。

プラン読み込み先プリザンターの設定
WindowsWindows の証明書ストアの Current User\MyStoreLocation を CurrentUser、StoreName を My
Windows コンテナー(Server Core)ファイルに加えて LocalMachine\My にも自動で読み込まれるStoreLocation を LocalMachine、StoreName を My
Linux(組み込み・カスタムコンテナー)ファイルとして /var/ssl/certs/<拇印>.der に置かれるだけX509Store からは見えないので、下記の方法にする
json
"IdentityProviders": [
    {
        "EntityId": "https://idp.example.com/...",
        "SignOnUrl": "https://idp.example.com/sso",
        "SigningCertificate": {
            "StoreName": "My",
            "StoreLocation": "CurrentUser",
            "X509FindType": "FindByThumbprint",
            "FindValue": "A1B2C3D4E5F6..."
        }
    }
]

WARNING

Windows プランでは、WEBSITE_LOAD_CERTIFICATES を設定しないと、アップロードした証明書がアプリのプロセスから参照できません。

Linux プランの場合

Linux の App Service では、WEBSITE_LOAD_CERTIFICATES の証明書は /var/ssl/certs にファイルとして置かれるだけで、Microsoft Learn でもファイルから読み込むコード例が示されています。プリザンターは証明書ファイルのパスを指定できず X509Store しか探さないため、この方法では SigningCertificate の証明書は見つかりません。Linux プランでは、Docker の手順で CurrentUser\My のストアを焼き込んだカスタムコンテナーを使ってください。

AWS ​

EC2 ​

通常の Linux サーバーと同じ手順です。OS に合わせて Linux の手順を参照してください。

  • Amazon Linux 2023:RHEL 系の手順
  • Ubuntu on EC2:Debian / Ubuntu 系の手順

Elastic Beanstalk ​

Docker プラットフォームを使う場合は、Docker の手順でストアを焼き込んだイメージをデプロイするのがいちばん確実です。

.NET の Linux プラットフォームで動かす場合は、.ebextensions で証明書とスクリプトを配置し、アプリの実行ユーザーで import-idp-cert.ps1 を実行します。インスタンスに PowerShell 7 が入っている必要があります。実行ユーザー名(下の例の pleasanter)は環境に合わせて置き換えてください(ps -o user= -C dotnet などで確認できます)。

yaml
files:
  "/etc/pleasanter/certs/idp-certificate.pem":
    mode: "000644"
    owner: root
    group: root
    content: |
      -----BEGIN CERTIFICATE-----
      MIIDxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
      (証明書の内容)
      -----END CERTIFICATE-----
  "/etc/pleasanter/certs/import-idp-cert.ps1":
    mode: "000644"
    owner: root
    group: root
    content: |
      # Linux の手順の import-idp-cert.ps1 と同じ内容

commands:
  01_import_idp_cert:
    command: "sudo -u pleasanter -H pwsh -NoProfile -File /etc/pleasanter/certs/import-idp-cert.ps1 -Path /etc/pleasanter/certs/idp-certificate.pem"

WARNING

IdP の署名証明書は公開鍵の証明書なので秘密情報ではありませんが、差し替えられると偽の IdP の署名を受け入れてしまいます。.ebextensions に証明書の内容を直接書く場合は、リポジトリの書き込み権限を十分に管理してください。

ECS(Fargate / EC2) ​

コンテナイメージに証明書ストアを焼き込むのが基本です。Docker の Dockerfile でカスタムイメージをビルドしてください。

証明書を差し替えるたびにイメージを作り直したくない場合は、Docker のボリュームの例と同じく、SDK コンテナで作ったストアのディレクトリ(x509stores)を EFS などのボリュームに置き、コンテナの /root/.dotnet/corefx/cryptography/x509stores にマウントします。証明書の PEM を Secrets Manager から環境変数やファイルで渡すだけでは、X509Store には入らないので読まれません。

Google Cloud ​

Cloud Run ​

コンテナベースのサービスなので、Docker の Dockerfile でストアを焼き込んだカスタムイメージをビルドし、Artifact Registry にプッシュしてデプロイします。

WARNING

Secret Manager のシークレットを .pem ファイルとしてマウントするだけでは、プリザンターは読みません(X509Store しか探さないため)。ストアはイメージに含めてください。

Compute Engine ​

通常の Linux サーバーと同じ手順です。OS に合わせて Linux の手順を参照してください。

環境別の設定サマリ ​

環境StoreLocationStoreName備考
Windows(IIS)LocalMachineMyアプリケーションプール ID に読み取り権限が必要
Windows(Kestrel)CurrentUserMy実行ユーザーの個人ストア
Linux 全般CurrentUserMy実行ユーザーで PowerShell 7 の X509Store.Add を実行し、~/.dotnet/corefx/cryptography/x509stores/my/ に入れる。LocalMachine は使えない
DockerCurrentUserMySDK イメージで作ったストアをイメージにコピーするか、ボリュームでマウントする
Azure App Service(Windows)CurrentUserMyWEBSITE_LOAD_CERTIFICATES の設定が必須
Azure App Service(Linux)CurrentUserMyストアを焼き込んだカスタムコンテナーを使う(WEBSITE_LOAD_CERTIFICATES はファイルを置くだけ)
AWS ECS / FargateCurrentUserMyコンテナイメージに焼き込むか、ボリュームでマウントする
Google Cloud RunCurrentUserMyコンテナイメージに焼き込む

トラブルシューティング ​

よくあるエラーと対処 ​

症状原因対処
SAML ログインで例外になる(証明書が見つからない)StoreLocation / StoreName / FindValue の不一致、ストアが存在しないSigningCertificate の設定値とインポート先が一致しているか確認する。ストアが無いと OpenExistingOnly で開けずに例外になる
拇印が一致しない拇印のコピーミス、大文字小文字の違いopenssl x509 -fingerprint で再確認し、コロンを除いた値を設定する
Linux で StoreLocation を LocalMachine にすると例外になるLinux の .NET は LocalMachine\My を開けないCurrentUser にし、実行ユーザーの CurrentUser\My にインポートする
Linux / Docker でインポートしたのに見つからない別のユーザー(root など)のホームにインポートした、update-ca-certificates や NSS の certutil だけで済ませたプリザンターの実行ユーザーで ls -la "$HOME/.dotnet/corefx/cryptography/x509stores/my/" を確認し、Linux の手順でインポートし直す
Linux で certutil -user -addstore がエラーになるWindows の certutil の書式で、Linux の NSS の certutil とは別物PowerShell 7 の X509Store.Add でインポートする(Linux の手順)
Azure App Service で証明書が読めないWindows プランは WEBSITE_LOAD_CERTIFICATES 未設定。Linux プランはファイルが置かれるだけで X509Store から見えないWindows プランはアプリケーション設定で拇印または * を設定する。Linux プランはストアを焼き込んだカスタムコンテナーにする
IIS で「アクセス拒否」エラーアプリプールの権限不足certlm.msc で証明書を右クリック →「すべてのタスク」→「秘密キーの管理」からアプリプール ID に読み取り権限を付与する

SysLogs テーブルで調べる ​

本体の SAML 認証処理(Saml.cs)は、SAML-MultiTenant で使うテナントごとのメタデータの読み込みに関するイベントを SysLogs テーブルに記録します(SetIdpConfiguration と SetIdpCache。Saml.cs)。Authentication.json の IdentityProviders に書いた IdP の証明書(SigningCertificate)は、後述の SetSPOptions の中で読み込まれるため、SysLogs には記録されません。

場面SysLogType値ErrMessage に含まれるキーワード
IdP キャッシュ登録成功Info10(正常時のログ)
SAML 設定が不完全(必須パラメータ不足)Warning50Saml settings is incomplete
メタデータが見つからないSystemError80Metadata not found
メタデータの形式が不正(証明書パース失敗を含む)SystemError80Invalid metadata format
メタデータ読み込み時の例外(X509Certificate2 関連など)Exception90例外メッセージ(e.Message)がそのまま記録される

Info・Warning・SystemError の行は Method 列に SetIdpConfiguration が記録されます。Exception の行は例外用の SysLogModel で記録されるため、Method 列は SetIdpConfiguration ではなく、そのときのリクエストのアクション名になります(SysLogModel.cs)。下の 1 つ目の SQL は Exception の行を拾わないので、2 つ目の SQL と組み合わせて使います。

SAML 関連のエラーを抽出する SQL:

sql
-- SAML 証明書関連のエラーを抽出(SystemError 以上)
SELECT
    [SysLogId],
    [CreatedTime],
    [SysLogType],
    [Method],
    [ErrMessage],
    [ErrStackTrace]
FROM [SysLogs]
WHERE [Method] LIKE '%SetIdpConfiguration%'
  AND [SysLogType] >= 80
ORDER BY [CreatedTime] DESC;
sql
-- SAML 証明書関連のエラーを抽出(SystemError 以上)
SELECT
    "SysLogId",
    "CreatedTime",
    "SysLogType",
    "Method",
    "ErrMessage",
    "ErrStackTrace"
FROM "SysLogs"
WHERE "Method" LIKE '%SetIdpConfiguration%'
  AND "SysLogType" >= 80
ORDER BY "CreatedTime" DESC;
sql
-- SAML 証明書関連のエラーを抽出(SystemError 以上)
SELECT
    `SysLogId`,
    `CreatedTime`,
    `SysLogType`,
    `Method`,
    `ErrMessage`,
    `ErrStackTrace`
FROM `SysLogs`
WHERE `Method` LIKE '%SetIdpConfiguration%'
  AND `SysLogType` >= 80
ORDER BY `CreatedTime` DESC;

例外メッセージから証明書関連のエラーを横断的に探す SQL:

sql
-- 証明書関連の例外を横断検索
SELECT
    [SysLogId],
    [CreatedTime],
    [SysLogType],
    [ErrMessage]
FROM [SysLogs]
WHERE [ErrMessage] LIKE '%certificate%'
   OR [ErrMessage] LIKE '%X509%'
   OR [ErrMessage] LIKE '%PEM%'
ORDER BY [CreatedTime] DESC;
sql
-- 証明書関連の例外を横断検索
SELECT
    "SysLogId",
    "CreatedTime",
    "SysLogType",
    "ErrMessage"
FROM "SysLogs"
WHERE "ErrMessage" LIKE '%certificate%'
   OR "ErrMessage" LIKE '%X509%'
   OR "ErrMessage" LIKE '%PEM%'
ORDER BY "CreatedTime" DESC;
sql
-- 証明書関連の例外を横断検索
SELECT
    `SysLogId`,
    `CreatedTime`,
    `SysLogType`,
    `ErrMessage`
FROM `SysLogs`
WHERE `ErrMessage` LIKE '%certificate%'
   OR `ErrMessage` LIKE '%X509%'
   OR `ErrMessage` LIKE '%PEM%'
ORDER BY `CreatedTime` DESC;

INFO

SysLogs へのデータベース記録は Parameters/SysLog.json の EnableLoggingToDatabase が true(既定値)のときに有効です。無効にしている場合は EnableLoggingToFile を true にし、NLog 経由のファイルログを確認してください。

WARNING

SetSPOptions 内では SysLogs への書き込みが行われません。SetSPOptions では SP 側の証明書(ServiceCertificates)に加えて、Authentication.json の IdentityProviders の署名証明書(SigningCertificate)も読み込みます(Saml.cs)。シングルテナントの SAML で証明書が読めないときは、ここで例外になるため、アプリケーションログ(stdout / stderr)を確認してください。

  • Windows(IIS): web.config で stdoutLogEnabled を true にし、stdoutLogFile に指定されたパス(既定は .\logs\stdout)のログファイルを確認する
  • Windows(Kestrel 直接実行): コンソールウィンドウの出力を確認する。サービス登録している場合は Windows イベントビューアーも確認する
  • Linux(systemd): journalctl -u pleasanter.service -e で直近のログを確認する
  • Docker: docker logs <コンテナ名> でコンテナの標準出力・標準エラーを確認する
  • Azure App Service: Azure ポータルの「ログストリーム」または Kudu(https://<app>.scm.azurewebsites.net)で確認する

証明書の有効期限 ​

期限切れの証明書ではログインに失敗するため、定期的に確認します。

bash
# 有効期限を確認
openssl x509 -in certificate.pem -noout -dates
# 出力例:
# notBefore=Jan  1 00:00:00 2026 GMT
# notAfter=Dec 31 23:59:59 2027 GMT
powershell
# PowerShell で有効期限を確認
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("certificate.pem")
$cert.NotAfter

WARNING

IdP 側で証明書が更新された場合は、プリザンター側でも新しい証明書をインポートし直し、Authentication.json の FindValue を新しい拇印に更新する必要があります。Linux / Docker では、新しい証明書も同じ実行ユーザーの CurrentUser\My に入れてください(Docker で焼き込んでいる場合はイメージの再ビルドが必要です)。

関連ページ ​

変更履歴

第6版証明書エラーの診断 SQL を3種類のDBMSに対応
第5版「外部連携・AI」「構築・運用」「内部実装を読む」に対応バージョンを表示
第4版Linux・Docker・クラウドでの証明書インポート手順を .NET の X509Store の仕様に合わせて書き直し
第3版「構築・運用」を 1.5.8.1 のソースで検証して修正
第2版記事のファイル名に並び順の番号を付け、元記事リンクを frontmatter の sources に移行
第1版「構築・運用」に証明書のインポートと添付ファイルの保存先を追加