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

SAML SSO

SnapOtter hỗ trợ SAML 2.0 cho đăng nhập một lần. Người dùng có thể đăng nhập qua một nhà cung cấp danh tính bên ngoài (Okta, Azure AD / Entra ID, Google Workspace, hoặc bất kỳ IdP SAML 2.0 chuẩn nào) thay cho xác thực bằng tên đăng nhập/mật khẩu cục bộ.

Tính năng doanh nghiệp

SAML SSO yêu cầu giấy phép team hoặc enterprise với tính năng saml_sso. Nếu SAML_ENABLED=true được đặt mà không có giấy phép hợp lệ, các route SAML sẽ được bỏ qua âm thầm và một cảnh báo được ghi log.

Điều kiện tiên quyết

  • Một instance SnapOtter đang chạy, truy cập được tại một URL công khai
  • EXTERNAL_URL được đặt thành URL công khai đó (ví dụ https://photos.example.com)
  • Một khóa giấy phép team hoặc enterprise với tính năng saml_sso
  • Quyền admin trên nhà cung cấp danh tính SAML của bạn

Bắt đầu nhanh

Thêm các biến môi trường này vào docker-compose.yml của bạn:

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

Khởi động lại container. Một nút "Sign in with SAML" (hoặc nhãn được đặt bởi SAML_PROVIDER_NAME) xuất hiện trên trang đăng nhập.

Tài liệu tham khảo cấu hình

BiếnMặc địnhMô tả
SAML_ENABLEDfalseBật đăng nhập SAML.
SAML_IDP_SSO_URLURL endpoint SSO của IdP. Bắt buộc khi SAML được bật.
SAML_IDP_CERTIFICATEChứng chỉ ký X.509 của IdP ở định dạng PEM (chính văn bản chứng chỉ, không phải đường dẫn tệp). Bắt buộc khi SAML được bật.
EXTERNAL_URLURL công khai nơi có thể truy cập SnapOtter. Bắt buộc khi SAML được bật.
SAML_ENTITY_ID${EXTERNAL_URL}/api/auth/saml/metadataSP Entity ID / Audience URI gửi đến IdP.
SAML_CALLBACK_URL${EXTERNAL_URL}/api/auth/saml/callbackURL Assertion Consumer Service (ACS).
SAML_AUTO_CREATE_USERStrueTự động tạo tài khoản người dùng cục bộ ở lần đăng nhập SAML đầu tiên.
SAML_AUTO_LINK_USERSfalseLiên kết một danh tính SAML với người dùng cục bộ hiện có nếu địa chỉ email trùng khớp.
SAML_DEFAULT_ROLEuserVai trò được gán cho người dùng SAML được tạo tự động. Một trong admin, editor, hoặc user.
SAML_PROVIDER_NAMENhãn hiển thị cho nút đăng nhập SAML trên frontend (ví dụ "Okta", "Azure AD"). Nếu để trống, nút sẽ ghi "SAML".
SAML_USERNAME_ATTRIBUTEThuộc tính assertion SAML dùng làm tên đăng nhập. Nếu để trống, sẽ dùng phần cục bộ của email, rồi đến NameID.
SAML_EMAIL_ATTRIBUTEemailThuộc tính assertion SAML dùng làm địa chỉ email của người dùng.

Máy chủ từ chối khởi động nếu SAML_ENABLED=true và bất kỳ biến nào trong ba biến bắt buộc (SAML_IDP_SSO_URL, SAML_IDP_CERTIFICATE, EXTERNAL_URL) bị thiếu.

Lưu ý bảo mật

Cả wantAuthnResponseSignedwantAssertionsSigned đều được đặt cứng thành true. SnapOtter từ chối các phản hồi SAML không được ký hoặc được ký không đúng cách. Assertion từ một IdP tin cậy được coi là đã xác minh email.

Chỉ hỗ trợ đăng nhập khởi tạo từ SP. SnapOtter không hỗ trợ đăng nhập khởi tạo từ IdP (không được yêu cầu) hay Single Logout (SLO). Đăng xuất khỏi SnapOtter không đăng xuất người dùng khỏi IdP.

Metadata và URL của SP

IdP của bạn cần ba giá trị từ SnapOtter:

TrườngGiá trị
ACS URL (Assertion Consumer Service)${EXTERNAL_URL}/api/auth/saml/callback
Entity ID / Audience URI${EXTERNAL_URL}/api/auth/saml/metadata
SP Metadata (XML)GET ${EXTERNAL_URL}/api/auth/saml/metadata

Ví dụ, nếu 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
  • Endpoint metadata: https://photos.example.com/api/auth/saml/metadata (trả về XML)

Một số IdP có thể import trực tiếp URL metadata của SP, tự động điền ACS URL và Entity ID.

Thiết lập nhà cung cấp

Okta

  1. Trong console admin của Okta, vào Applications > Create App Integration.
  2. Chọn SAML 2.0 và nhấn Next.
  3. Đặt một tên (ví dụ "SnapOtter") và nhấn Next.
  4. Cấu hình các thiết lập SAML:
    • Single sign-on URL: ACS URL của bạn (ví dụ https://photos.example.com/api/auth/saml/callback)
    • Audience URI (SP Entity ID): Entity ID của bạn (ví dụ https://photos.example.com/api/auth/saml/metadata)
    • Name ID format: EmailAddress
    • Application username: Email
  5. Trong Attribute Statements, thêm email ánh xạ tới user.email.
  6. Nhấn Next, rồi Finish.
  7. Vào tab Sign On, nhấn View SAML setup instructions, và sao chép:
    • Identity Provider Single Sign-On URL vào SAML_IDP_SSO_URL
    • X.509 Certificate vào SAML_IDP_CERTIFICATE

Azure AD / Entra ID

  1. Trong Azure portal, vào Microsoft Entra ID > Enterprise applications > New application.
  2. Nhấn Create your own application, đặt tên là "SnapOtter", và chọn Integrate any other application you don't find in the gallery.
  3. Vào Single sign-on > SAML và nhấn Edit ở phần Basic SAML Configuration:
    • Identifier (Entity ID): Entity ID của bạn (ví dụ https://photos.example.com/api/auth/saml/metadata)
    • Reply URL (ACS URL): ACS URL của bạn (ví dụ https://photos.example.com/api/auth/saml/callback)
  4. Trong SAML Certificates, tải xuống Certificate (Base64).
  5. Trong Set up SnapOtter, sao chép Login URL.
  6. Đặt SAML_IDP_SSO_URL thành Login URL và SAML_IDP_CERTIFICATE thành nội dung chứng chỉ đã tải xuống.
  7. Gán người dùng hoặc nhóm vào ứng dụng trong Users and groups.

Google Workspace

  1. Trong console admin của Google, vào Apps > Web and mobile apps > Add app > Add custom SAML app.
  2. Đặt tên ứng dụng là "SnapOtter" và nhấn Continue.
  3. Trên trang Google Identity Provider details, sao chép SSO URL và tải xuống Certificate. Nhấn Continue.
  4. Cấu hình chi tiết Service Provider:
    • ACS URL: ACS URL của bạn (ví dụ https://photos.example.com/api/auth/saml/callback)
    • Entity ID: Entity ID của bạn (ví dụ https://photos.example.com/api/auth/saml/metadata)
    • Name ID format: EMAIL
    • Name ID: Basic Information > Primary email
  5. Nhấn Continue, rồi Finish.
  6. Bật ứng dụng ON cho các đơn vị tổ chức của bạn.
  7. Đặt SAML_IDP_SSO_URL thành SSO URL từ bước 3 và SAML_IDP_CERTIFICATE thành nội dung chứng chỉ đã tải xuống.

IdP SAML 2.0 chung

Đối với bất kỳ nhà cung cấp danh tính tuân thủ SAML 2.0 nào:

  1. Tạo một ứng dụng/nhà cung cấp dịch vụ SAML mới trong IdP của bạn.
  2. Đặt ACS URL thành ${EXTERNAL_URL}/api/auth/saml/callback.
  3. Đặt Entity ID / Audience thành ${EXTERNAL_URL}/api/auth/saml/metadata.
  4. Cấu hình IdP để gửi email của người dùng trong một thuộc tính có tên email (hoặc đặt SAML_EMAIL_ATTRIBUTE để khớp với tên thuộc tính của IdP của bạn).
  5. Sao chép IdP SSO URLchứng chỉ ký vào SAML_IDP_SSO_URLSAML_IDP_CERTIFICATE.

Cấp phát người dùng

Tự động tạo

Khi SAML_AUTO_CREATE_USERStrue (mặc định), một tài khoản người dùng cục bộ được tạo lần đầu tiên khi ai đó đăng nhập qua SAML. Vai trò được đặt thành SAML_DEFAULT_ROLE.

Tên đăng nhập được suy ra theo thứ tự này:

  1. Giá trị của thuộc tính assertion được chỉ định bởi SAML_USERNAME_ATTRIBUTE (nếu được đặt và có mặt)
  2. Phần cục bộ của địa chỉ email (mọi thứ trước @)
  3. SAML NameID

Nếu xảy ra trùng tên đăng nhập, một hậu tố số sẽ được thêm vào (ví dụ jane trở thành jane_2).

Khi SAML_AUTO_LINK_USERStrue, SnapOtter liên kết một danh tính SAML với tài khoản cục bộ hiện có nếu địa chỉ email trùng khớp. Điều này hữu ích khi bạn đã tạo sẵn tài khoản người dùng và muốn họ bắt đầu dùng SSO mà không mất dữ liệu.

WARNING

Chỉ bật tự động liên kết nếu bạn tin tưởng IdP SAML của mình xác minh địa chỉ email. Một email chưa được xác minh từ một IdP cấu hình sai có thể cho phép ai đó chiếm quyền tài khoản của người dùng khác.

Ánh xạ thuộc tính

Trường SnapOtterNguồnCấu hình
EmailThuộc tính assertionSAML_EMAIL_ATTRIBUTE (mặc định: email)
Tên đăng nhậpThuộc tính assertion, email, hoặc NameIDSAML_USERNAME_ATTRIBUTE (xem thứ tự suy ra ở trên)
External IDNameIDLuôn là SAML NameID, không thể cấu hình

Bắt buộc SSO

Nếu bạn muốn yêu cầu tất cả người dùng đăng nhập qua SAML (hoặc OIDC) và chặn đăng nhập bằng mật khẩu cục bộ, hãy bật bắt buộc SSO:

  1. Đảm bảo tính năng doanh nghiệp sso_enforcement có giấy phép (có sẵn trên gói team và enterprise).
  2. Trong Admin Settings > Security, bật SSO Enforcement.
  3. Đặt một break-glass username: đây là tài khoản cục bộ duy nhất vẫn có thể đăng nhập bằng mật khẩu, cho truy cập khẩn cấp nếu không thể truy cập IdP.

Khi bắt buộc SSO đang hoạt động, bất kỳ nỗ lực đăng nhập cục bộ nào (ngoài trừ người dùng break-glass) sẽ trả về lỗi 403 với thông báo "Local password login is disabled. Please use SSO."

TIP

Luôn cấu hình một break-glass username trước khi bật bắt buộc SSO. Nếu không, bạn có thể bị khóa khỏi SnapOtter nếu IdP của bạn ngừng hoạt động.

Dùng SAML song song với OIDC

SAML và OIDC có thể được bật đồng thời. Khi cả hai đang hoạt động, trang đăng nhập hiển thị các nút riêng cho từng nhà cung cấp (được gắn nhãn bởi SAML_PROVIDER_NAMEOIDC_PROVIDER_NAME). Người dùng có thể đăng nhập bằng bất kỳ phương thức nào.

Cả hai nhà cung cấp chia sẻ cùng các thiết lập tự động tạo, tự động liên kết và bắt buộc SSO một cách độc lập: mỗi nhà cung cấp có các biến *_AUTO_CREATE_USERS, *_AUTO_LINK_USERS, và *_DEFAULT_ROLE riêng.

Khắc phục sự cố

Xác thực assertion thất bại

Chữ ký phản hồi SAML hoặc chữ ký assertion không thể được xác minh. Kiểm tra:

  • Chứng chỉ trong SAML_IDP_CERTIFICATE khớp với chứng chỉ ký hiện tại trong IdP của bạn (chứng chỉ có xoay vòng, vì vậy hãy kiểm tra hạn dùng)
  • Chứng chỉ ở định dạng PEM (bắt đầu bằng -----BEGIN CERTIFICATE-----)
  • Chứng chỉ là toàn bộ văn bản, không phải đường dẫn tệp
  • ACS URL và Entity ID được cấu hình trong IdP của bạn khớp chính xác với các giá trị của SnapOtter (scheme, host, cổng, đường dẫn)

Thiếu thuộc tính

Nếu tên đăng nhập hoặc email trống sau khi đăng nhập, IdP của bạn có thể không gửi các thuộc tính mong đợi. Kiểm tra:

  • IdP của bạn được cấu hình để phát hành thuộc tính email (hoặc bất kỳ giá trị nào SAML_EMAIL_ATTRIBUTE được đặt thành)
  • Nếu dùng SAML_USERNAME_ATTRIBUTE, xác minh rằng thuộc tính đó có trong assertion
  • Một số IdP yêu cầu cấu hình ánh xạ thuộc tính rõ ràng trước khi phát hành claim

Lệch đồng hồ

Các assertion SAML bao gồm điều kiện dấu thời gian (NotBefore, NotOnOrAfter). Nếu đồng hồ máy chủ của bạn và đồng hồ IdP lệch nhau, việc xác thực assertion sẽ thất bại. Chạy NTP trên cả hai máy để giữ đồng hồ đồng bộ.

"SAML is enabled via env but saml_sso enterprise feature is not licensed"

Cảnh báo này xuất hiện trong log máy chủ khi SAML_ENABLED=true nhưng giấy phép không bao gồm tính năng saml_sso. Xác minh khóa giấy phép và gói của bạn. Tính năng saml_sso có sẵn trên gói team và enterprise.

Đăng nhập chuyển hướng lại kèm lỗi

Nếu nhấn nút đăng nhập SAML chuyển hướng lại về trang đăng nhập kèm một lỗi, hãy kiểm tra log máy chủ để biết chi tiết. Nguyên nhân phổ biến:

  • Không thể truy cập IdP SSO URL từ máy chủ
  • IdP từ chối yêu cầu xác thực (kiểm tra log kiểm toán của IdP)
  • IdP trả về một phản hồi không được ký (SnapOtter yêu cầu cả phản hồi và assertion đều được ký)