Trang này được dịch tự động bằng máy. Phát hiện lỗi?Giúp cải thiện bản dịch.
Skip to content

OIDC / Đăng nhập một lần ​

SnapOtter hỗ trợ OpenID Connect (OIDC) cho đăng nhập một lần. Người dùng có thể đăng nhập bằng nhà cung cấp danh tính bên ngoài như Keycloak, Authentik, Google hoặc Microsoft Entra ID thay cho (hoặc song song với) xác thực bằng tên đăng nhập/mật khẩu cục bộ.

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"
      OIDC_ENABLED: "true"
      OIDC_ISSUER_URL: "https://auth.example.com/realms/myrealm"
      OIDC_CLIENT_ID: "snapotter"
      OIDC_CLIENT_SECRET: "your-secret-here"

Redirect URI cho nhà cung cấp của bạn luôn là:

${EXTERNAL_URL}/api/auth/oidc/callback

Ví dụ, nếu EXTERNAL_URL là https://photos.example.com, hãy cấu hình redirect URI của nhà cung cấp thành https://photos.example.com/api/auth/oidc/callback.

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

BiếnMặc địnhMô tả
OIDC_ENABLEDfalseBật đăng nhập OIDC. Một nút "Sign in with SSO" xuất hiện trên trang đăng nhập.
OIDC_ISSUER_URLURL issuer của nhà cung cấp. Phải hỗ trợ OIDC Discovery (/.well-known/openid-configuration).
OIDC_CLIENT_IDOAuth client ID đã đăng ký với nhà cung cấp của bạn.
OIDC_CLIENT_SECRETOAuth client secret.
OIDC_SCOPESopenid profile emailDanh sách các scope cần yêu cầu, ngăn cách bằng dấu cách.
OIDC_AUTO_CREATE_USERStrueTự động tạo tài khoản người dùng cục bộ ở lần đăng nhập OIDC đầu tiên.
OIDC_DEFAULT_ROLEuserVai trò được gán cho người dùng OIDC được tạo tự động. Một trong admin, editor, hoặc user.
OIDC_AUTO_LINK_USERSfalseLiên kết một danh tính OIDC với người dùng cục bộ hiện có nếu địa chỉ email trùng khớp.
OIDC_PROVIDER_NAMETên hiển thị trên nút đăng nhập (ví dụ "Keycloak", "Google"). Nếu để trống, nút sẽ ghi "SSO".
OIDC_CLOCK_TOLERANCE30Dung sai lệch đồng hồ tính bằng giây khi xác thực token.
OIDC_USERNAME_CLAIMpreferred_usernameClaim trong ID token dùng làm tên đăng nhập cho tài khoản mới.
EXTERNAL_URLURL công khai nơi có thể truy cập SnapOtter. Bắt buộc để OIDC dựng đúng redirect URI.
COOKIE_SECRETtự động tạoSecret để ký cookie phiên. Đặt giá trị này rõ ràng khi chạy nhiều replica.

Hướng dẫn cho nhà cung cấp ​

Keycloak ​

  1. Tạo một realm mới (hoặc dùng realm có sẵn).
  2. Vào Clients và tạo một client mới:
    • Client ID: snapotter
    • Client authentication: On (confidential)
    • Authentication flow: Standard flow (Authorization Code)
  3. Trong tab Settings của client, đặt Valid redirect URIs thành callback URL của bạn (ví dụ https://photos.example.com/api/auth/oidc/callback).
  4. Sao chép Client secret từ tab Credentials.
  5. Đặt OIDC_ISSUER_URL thành https://keycloak.example.com/realms/your-realm.

Authentik ​

  1. Trong giao diện admin, vào Applications > Providers và tạo một OAuth2/OpenID Provider mới.
    • Client type: Confidential
    • Redirect URIs: Callback URL của bạn
    • Signing key: Chọn một khóa có sẵn hoặc tạo mới
  2. Tạo một Application và liên kết nó với provider.
  3. Sao chép Client ID và Client Secret từ cài đặt provider.
  4. Đặt OIDC_ISSUER_URL thành https://authentik.example.com/application/o/snapotter/ (dấu gạch chéo ở cuối quan trọng).

Google ​

  1. Vào Google Cloud Console.
  2. Tạo một dự án (hoặc chọn dự án có sẵn).
  3. Điều hướng đến APIs & Services > OAuth consent screen và cấu hình nó.
  4. Vào APIs & Services > Credentials và tạo một OAuth 2.0 Client ID:
    • Application type: Web application
    • Authorized redirect URIs: Callback URL của bạn
  5. Sao chép Client ID và Client secret.
  6. Đặt OIDC_ISSUER_URL thành https://accounts.google.com.
  7. Đặt OIDC_USERNAME_CLAIM thành email (Google không cung cấp preferred_username).

Azure AD / Entra ID ​

  1. Trong Azure portal, vào Microsoft Entra ID > App registrations > New registration.
  2. Đặt tên ứng dụng là "SnapOtter". Ở mục Redirect URI, chọn nền tảng Web và nhập callback URL của bạn (ví dụ https://photos.example.com/api/auth/oidc/callback). Đừng chọn Single-page application: SnapOtter xác thực bằng client secret, thứ mà Entra ID từ chối trên các đăng ký SPA.
  3. Sao chép Application (client) ID và Directory (tenant) ID từ trang Overview.
  4. Vào Certificates & secrets > New client secret và sao chép ngay Value của secret. Giá trị này chỉ hiển thị một lần, và Secret ID nằm bên cạnh không phải là secret.
  5. Đặt OIDC_ISSUER_URL thành https://login.microsoftonline.com/<tenant-id>/v2.0, dùng Directory (tenant) ID từ bước 3.
  6. Giữ OIDC_USERNAME_CLAIM ở giá trị mặc định. Entra ID cung cấp preferred_username, nên ở đây không cần dùng cách ghi đè thành email như trong hướng dẫn cho Google.

Luôn dùng tenant ID của bạn trong issuer URL, không dùng common hay organizations. Các endpoint đa tenant đó công bố nguyên văn chuỗi mẫu {tenantid} làm issuer, khiến bước xác thực OIDC discovery thất bại.

WARNING

preferred_username của Entra ID bám theo user principal name, giá trị này thay đổi khi người dùng bị đổi tên hoặc được chuyển sang tenant khác. SnapOtter chỉ đọc claim này một lần, tại lần đăng nhập đầu tiên, nên sau đó tài khoản giữ nguyên tên đăng nhập ban đầu. Dù thế nào thì việc đăng nhập vẫn hoạt động: người dùng quay lại được khớp bằng subject ổn định của token, chứ không phải bằng tên đăng nhập.

Chuyển sang Entra ID không tắt đăng nhập bằng mật khẩu. Xem Tắt đăng nhập cục bộ.

Okta và các nhà cung cấp khác ​

Bất kỳ nhà cung cấp nào hỗ trợ OIDC Discovery đều hoạt động theo cùng một cách: tạo một confidential web client với callback URL của bạn, rồi trỏ OIDC_ISSUER_URL đến issuer. Với Okta, tạo một ứng dụng với phương thức đăng nhập OIDC - OpenID Connect và loại Web Application, rồi dùng miền Okta của bạn làm issuer (ví dụ https://your-company.okta.com).

SnapOtter không ánh xạ các nhóm của nhà cung cấp danh tính sang vai trò. Người dùng SSO mới nhận OIDC_DEFAULT_ROLE, admin thay đổi vai trò trong Settings > Users, và việc yêu cầu các claim nhóm qua OIDC_SCOPES không có tác dụng.

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

Tự động tạo ​

Khi OIDC_AUTO_CREATE_USERS là true (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 OIDC. Tên đăng nhập được lấy từ claim được chỉ định bởi OIDC_USERNAME_CLAIM, và vai trò được đặt thành OIDC_DEFAULT_ROLE.

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 OIDC_AUTO_LINK_USERS là true, SnapOtter liên kết một danh tính OIDC 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 nhà cung cấp OIDC của mình xác minh địa chỉ email. Một email chưa được xác minh có thể cho phép ai đó chiếm quyền tài khoản của người dùng khác.

Tắt đăng nhập cục bộ ​

OIDC không tắt đăng nhập bằng tên đăng nhập/mật khẩu cục bộ. Cả hai phương thức vẫn khả dụng. Admin vẫn có thể đăng nhập bằng thông tin đăng nhập cục bộ nếu không thể truy cập nhà cung cấp OIDC.

Chứng chỉ tự ký ​

Nếu nhà cung cấp OIDC của bạn dùng chứng chỉ tự ký hoặc chứng chỉ CA riêng, hãy mount bundle CA vào container và trỏ NODE_EXTRA_CA_CERTS đến nó:

yaml
services:
  SnapOtter:
    image: snapotter/snapotter:latest
    volumes:
      - ./my-ca.pem:/etc/ssl/certs/custom-ca.pem:ro
    environment:
      NODE_EXTRA_CA_CERTS: /etc/ssl/certs/custom-ca.pem
      OIDC_ENABLED: "true"
      OIDC_ISSUER_URL: "https://auth.internal.example.com/realms/myrealm"
      OIDC_CLIENT_ID: "snapotter"
      OIDC_CLIENT_SECRET: "your-secret-here"

DANGER

Đừng đặt NODE_TLS_REJECT_UNAUTHORIZED=0. Việc này tắt toàn bộ xác minh TLS và là một rủi ro bảo mật.

Issuer dùng http không mã hóa ​

SnapOtter chỉ chấp nhận URL issuer http:// khi EXTERNAL_URL cũng là http không mã hóa, phù hợp với môi trường thử nghiệm cục bộ hoặc trong mạng LAN. Khi đó, quá trình discovery, việc trao đổi mã đăng nhập và các token đều đi qua mạng mà không được mã hóa, nên SnapOtter ghi một cảnh báo khi khởi động, nêu rõ host của issuer. Với EXTERNAL_URL là https://, issuer dùng http sẽ bị từ chối khi đăng nhập và cảnh báo khởi động sẽ nêu điều đó. Trong cả hai trường hợp, cách khắc phục là phục vụ nhà cung cấp danh tính của bạn qua https.

Khắc phục sự cố ​

Không khớp Redirect URI ​

Lỗi phổ biến nhất. Kiểm tra những khác biệt này giữa những gì nhà cung cấp của bạn mong đợi và những gì SnapOtter gửi:

  • http so với https - scheme phải trùng khớp chính xác
  • Dấu gạch chéo cuối - một số nhà cung cấp khá nghiêm về điều này
  • Số cổng - hãy đưa cổng vào nếu nó không phải cổng chuẩn
  • Đường dẫn - phải là /api/auth/oidc/callback

Kiểm tra kỹ EXTERNAL_URL. Nó phải khớp với URL mà người dùng nhập vào trình duyệt.

UNABLE_TO_VERIFY_LEAF_SIGNATURE ​

Nhà cung cấp OIDC đang dùng một chứng chỉ mà Node.js không tin cậy. Xem Chứng chỉ tự ký ở trên.

Lỗi lệch đồng hồ ​

Nếu đồng hồ máy chủ của bạn và đồng hồ của nhà cung cấp OIDC lệch nhau, việc xác thực token có thể thất bại. Tăng OIDC_CLOCK_TOLERANCE (mặc định là 30 giây). Cách khắc phục tốt hơn là chạy NTP trên cả hai máy.

"OIDC provider unreachable" ​

SnapOtter lấy tài liệu discovery của nhà cung cấp lúc khởi động và trong quá trình đăng nhập. Kiểm tra:

  • Phân giải DNS từ bên trong container Docker (docker exec snapotter nslookup auth.example.com)
  • Quy tắc tường lửa giữa container và nhà cung cấp
  • Giá trị OIDC_ISSUER_URL - nó phải truy cập được từ máy chủ, chứ không chỉ từ trình duyệt của bạn

Thiếu claim ​

Nếu tên đăng nhập hoặc email trống sau khi đăng nhập, nhà cung cấp của bạn có thể không trả về các claim mong đợi. Xác minh:

  • Các scope được cấu hình trong OIDC_SCOPES có bao gồm profile và email
  • Nhà cung cấp được cấu hình để đưa claim được chỉ định trong OIDC_USERNAME_CLAIM vào ID token
  • Một số nhà cung cấp yêu cầu cấu hình mapper/scope rõ ràng để phát hành claim