This page was machine-translated. Spotted a mistake?Help improve it.
Skip to content

SAML SSO

SnapOtter はシングルサインオンのために SAML 2.0 をサポートしています。ユーザーは、ローカルのユーザー名/パスワード認証の代わりに、外部 ID プロバイダー(Okta、Azure AD / Entra ID、Google Workspace、または任意の標準 SAML 2.0 IdP)経由でログインできます。

エンタープライズ機能

SAML SSO には、saml_sso 機能を含む team または enterprise ライセンスが必要です。有効なライセンスなしに SAML_ENABLED=true が設定されている場合、SAML ルートは通知なくスキップされ、警告がログに記録されます。

前提条件

  • 公開 URL で到達可能な、稼働中の SnapOtter インスタンス
  • その公開 URL に設定された EXTERNAL_URL(例: https://photos.example.com
  • saml_sso 機能を含む team または enterprise のライセンスキー
  • SAML ID プロバイダーへの管理者アクセス

クイックスタート

これらの環境変数を docker-compose.yml に追加します:

yaml
services:
  snapotter:
    image: snapotter/snapotter:latest
    environment:
      EXTERNAL_URL: "https://photos.example.com"
      SNAPOTTER_LICENSE_KEY: "your-license-key"
      SAML_ENABLED: "true"
      SAML_IDP_SSO_URL: "https://idp.example.com/sso/saml"
      SAML_IDP_CERTIFICATE: |
        MIICpDCCAYwCCQDU+pQ4pHgSpDANBgkqhkiG9w0BAQsFADAUMRIw
        ...your IdP's signing certificate in PEM format...
        EAYHKoZIzj0CAQYFK4EEACIDYgAE

コンテナを再起動します。ログインページに「SAML でサインイン」ボタン(または SAML_PROVIDER_NAME で設定されたラベル)が表示されます。

設定リファレンス

変数デフォルト説明
SAML_ENABLEDfalseSAML ログインを有効にします。
SAML_IDP_SSO_URLIdP の SSO エンドポイント URL。SAML が有効な場合は 必須
SAML_IDP_CERTIFICATEPEM 形式の IdP の X.509 署名証明書(ファイルパスではなく証明書のテキストそのもの)。SAML が有効な場合は 必須
EXTERNAL_URLSnapOtter に到達できる公開 URL。SAML が有効な場合は 必須
SAML_ENTITY_ID${EXTERNAL_URL}/api/auth/saml/metadataIdP に送信される SP Entity ID / Audience URI。
SAML_CALLBACK_URL${EXTERNAL_URL}/api/auth/saml/callbackAssertion Consumer Service (ACS) URL。
SAML_AUTO_CREATE_USERStrue初回 SAML ログイン時にローカルユーザーアカウントを自動作成します。
SAML_AUTO_LINK_USERSfalseメールアドレスが一致する場合、SAML ID を既存のローカルユーザーにリンクします。
SAML_DEFAULT_ROLEuser自動作成された SAML ユーザーに割り当てられるロール。admineditoruser のいずれか。
SAML_PROVIDER_NAMEフロントエンドの SAML ログインボタンの表示ラベル(例:「Okta」、「Azure AD」)。空の場合、ボタンには「SAML」と表示されます。
SAML_USERNAME_ATTRIBUTEユーザー名として使用される SAML アサーション属性。空の場合、メールのローカル部分、次に NameID にフォールバックします。
SAML_EMAIL_ATTRIBUTEemailユーザーのメールアドレスとして使用される SAML アサーション属性。

SAML_ENABLED=true で、3 つの必須変数(SAML_IDP_SSO_URLSAML_IDP_CERTIFICATEEXTERNAL_URL)のいずれかが欠けている場合、サーバーは起動を拒否します。

セキュリティに関する注意

wantAuthnResponseSignedwantAssertionsSigned はどちらも true にハードコードされています。SnapOtter は署名されていない、または不適切に署名された SAML レスポンスを拒否します。信頼された IdP からのアサーションは、メール検証済みとして扱われます。

SP 起点のログインのみがサポートされています。SnapOtter は IdP 起点(未承諾)のログインやシングルログアウト (SLO) をサポートしていません。SnapOtter からログアウトしても、ユーザーは IdP からログアウトされません。

SP メタデータと URL

IdP には SnapOtter から 3 つの値が必要です:

フィールド
ACS URL(Assertion Consumer Service)${EXTERNAL_URL}/api/auth/saml/callback
Entity ID / Audience URI${EXTERNAL_URL}/api/auth/saml/metadata
SP メタデータ(XML)GET ${EXTERNAL_URL}/api/auth/saml/metadata

たとえば、EXTERNAL_URLhttps://photos.example.com の場合:

  • ACS URL: https://photos.example.com/api/auth/saml/callback
  • Entity ID: https://photos.example.com/api/auth/saml/metadata
  • メタデータエンドポイント: https://photos.example.com/api/auth/saml/metadata(XML を返します)

一部の IdP は SP メタデータ URL を直接インポートでき、これにより ACS URL と Entity ID が自動入力されます。

プロバイダーのセットアップ

Okta

  1. Okta 管理コンソールで、Applications > Create App Integration に移動します。
  2. SAML 2.0 を選択して Next をクリックします。
  3. 名前(例:「SnapOtter」)を設定して Next をクリックします。
  4. SAML 設定を構成します:
    • Single sign-on URL: あなたの ACS URL(例: https://photos.example.com/api/auth/saml/callback
    • Audience URI (SP Entity ID): あなたの Entity ID(例: https://photos.example.com/api/auth/saml/metadata
    • Name ID format: EmailAddress
    • Application username: Email
  5. Attribute Statements で、user.email にマッピングされた email を追加します。
  6. Next をクリックし、次に Finish をクリックします。
  7. Sign On タブに移動し、View SAML setup instructions をクリックして、以下をコピーします:
    • Identity Provider Single Sign-On URLSAML_IDP_SSO_URL
    • X.509 CertificateSAML_IDP_CERTIFICATE

Azure AD / Entra ID

  1. Azure ポータルで、Microsoft Entra ID > Enterprise applications > New application に移動します。
  2. Create your own application をクリックし、「SnapOtter」と名前を付け、Integrate any other application you don't find in the gallery を選択します。
  3. Single sign-on > SAML に移動し、Basic SAML Configuration セクションで Edit をクリックします:
    • Identifier (Entity ID): あなたの Entity ID(例: https://photos.example.com/api/auth/saml/metadata
    • Reply URL (ACS URL): あなたの ACS URL(例: https://photos.example.com/api/auth/saml/callback
  4. SAML Certificates で、Certificate (Base64) をダウンロードします。
  5. Set up SnapOtter で、Login URL をコピーします。
  6. SAML_IDP_SSO_URL を Login URL に、SAML_IDP_CERTIFICATE をダウンロードした証明書の内容に設定します。
  7. Users and groups でアプリケーションにユーザーまたはグループを割り当てます。

Google Workspace

  1. Google 管理コンソールで、Apps > Web and mobile apps > Add app > Add custom SAML app に移動します。
  2. アプリに「SnapOtter」と名前を付け、Continue をクリックします。
  3. Google Identity Provider details ページで、SSO URL をコピーし、Certificate をダウンロードします。Continue をクリックします。
  4. Service Provider の詳細を設定します:
    • ACS URL: あなたの ACS URL(例: https://photos.example.com/api/auth/saml/callback
    • Entity ID: あなたの Entity ID(例: https://photos.example.com/api/auth/saml/metadata
    • Name ID format: EMAIL
    • Name ID: Basic Information > Primary email
  5. Continue をクリックし、次に Finish をクリックします。
  6. 組織部門に対してアプリを ON にします。
  7. SAML_IDP_SSO_URL をステップ 3 の SSO URL に、SAML_IDP_CERTIFICATE をダウンロードした証明書の内容に設定します。

汎用 SAML 2.0 IdP

任意の SAML 2.0 準拠の ID プロバイダーの場合:

  1. IdP に新しい SAML アプリケーション/サービスプロバイダーを作成します。
  2. ACS URL${EXTERNAL_URL}/api/auth/saml/callback に設定します。
  3. Entity ID / Audience${EXTERNAL_URL}/api/auth/saml/metadata に設定します。
  4. email という名前の属性でユーザーのメールを送信するように IdP を設定します(または、IdP の属性名に合わせて SAML_EMAIL_ATTRIBUTE を設定します)。
  5. IdP SSO URL署名証明書SAML_IDP_SSO_URLSAML_IDP_CERTIFICATE にコピーします。

ユーザープロビジョニング

自動作成

SAML_AUTO_CREATE_USERStrue(デフォルト)の場合、誰かが初めて SAML 経由でログインしたときにローカルユーザーアカウントが作成されます。ロールは SAML_DEFAULT_ROLE に設定されます。

ユーザー名は次の順序で導出されます:

  1. SAML_USERNAME_ATTRIBUTE で指定されたアサーション属性の値(設定されていて存在する場合)
  2. メールアドレスのローカル部分(@ より前のすべて)
  3. SAML NameID

ユーザー名の衝突が発生した場合、数値のサフィックスが追加されます(例: janejane_2 になります)。

SAML_AUTO_LINK_USERStrue の場合、メールアドレスが一致すれば、SnapOtter は SAML ID を既存のローカルアカウントにリンクします。これは、事前に作成したユーザーアカウントがあり、データを失うことなく SSO の使用を開始させたい場合に便利です。

WARNING

自動リンクは、SAML IdP がメールアドレスを検証することを信頼できる場合にのみ有効にしてください。設定が誤った IdP からの検証されていないメールにより、誰かが別のユーザーのアカウントを乗っ取れる可能性があります。

属性マッピング

SnapOtter フィールドソース設定
メールアサーション属性SAML_EMAIL_ATTRIBUTE(デフォルト: email
ユーザー名アサーション属性、メール、または NameIDSAML_USERNAME_ATTRIBUTE(上記の導出順序を参照)
外部 IDNameID常に SAML NameID で、設定不可

SSO の強制

すべてのユーザーに SAML(または OIDC)経由でのログインを要求し、ローカルパスワードログインをブロックしたい場合は、SSO の強制を有効にします:

  1. sso_enforcement エンタープライズ機能がライセンスされていることを確認します(team および enterprise プランで利用可能)。
  2. Admin Settings > Security で、SSO Enforcement をオンに切り替えます。
  3. break-glass ユーザー名 を設定します。これは、IdP に到達できない場合の緊急アクセス用に、引き続きパスワードでログインできる唯一のローカルアカウントです。

SSO の強制が有効な場合、(break-glass ユーザーを除く)ローカルログインの試行は「Local password login is disabled. Please use SSO.」というメッセージとともに 403 エラーを返します。

TIP

SSO の強制を有効にする前に、必ず break-glass ユーザー名を設定してください。それがないと、IdP がダウンした場合に SnapOtter からロックアウトされる可能性があります。

OIDC と併用した SAML の使用

SAML と OIDC は同時に有効にできます。両方が有効な場合、ログインページには各プロバイダー用の個別のボタン(SAML_PROVIDER_NAMEOIDC_PROVIDER_NAME でラベル付け)が表示されます。ユーザーはどちらの方法でもログインできます。

両方のプロバイダーは、自動作成、自動リンク、SSO 強制の設定を独立して共有します。それぞれが独自の *_AUTO_CREATE_USERS*_AUTO_LINK_USERS*_DEFAULT_ROLE 変数を持ちます。

トラブルシューティング

アサーションの検証に失敗

SAML レスポンスの署名またはアサーションの署名を検証できませんでした。次を確認してください:

  • SAML_IDP_CERTIFICATE の証明書が IdP の現在の署名証明書と一致している(証明書はローテーションされるため、有効期限を確認してください)
  • 証明書が PEM 形式である(-----BEGIN CERTIFICATE----- で始まる)
  • 証明書がファイルパスではなく、全文である
  • IdP に設定された ACS URL と Entity ID が SnapOtter の値と正確に一致している(スキーム、ホスト、ポート、パス)

属性の欠落

ログイン後にユーザー名やメールが空の場合、IdP が期待される属性を送信していない可能性があります。次を確認してください:

  • IdP が email 属性(または SAML_EMAIL_ATTRIBUTE に設定されている値)を提供するように設定されている
  • SAML_USERNAME_ATTRIBUTE を使用している場合、その属性がアサーションに含まれていることを確認してください
  • 一部の IdP では、クレームを提供する前に明示的な属性マッピング設定が必要です

クロックスキュー

SAML アサーションにはタイムスタンプ条件(NotBeforeNotOnOrAfter)が含まれます。サーバーの時刻と IdP の時刻が同期していない場合、アサーションの検証は失敗します。時刻を揃えておくために、両方のマシンで NTP を実行してください。

「SAML is enabled via env but saml_sso enterprise feature is not licensed」

この警告は、SAML_ENABLED=true であるがライセンスに saml_sso 機能が含まれていない場合にサーバーログに表示されます。ライセンスキーとプランを確認してください。saml_sso 機能は team および enterprise プランで利用可能です。

ログインがエラーとともに戻される

SAML ログインボタンをクリックするとエラーとともにログインページに戻される場合は、詳細についてサーバーログを確認してください。一般的な原因:

  • IdP SSO URL がサーバーから到達不能である
  • IdP が認証リクエストを拒否した(IdP の監査ログを確認してください)
  • IdP が署名されていないレスポンスを返した(SnapOtter はレスポンスとアサーションの両方が署名されていることを要求します)