Đặc tả tích hợp SSO·SCIM
Các giá trị và hành vi mà người phụ trách IdP và nhà phát triển cần để thiết lập tích hợp OIDC, SAML 2.0 và SCIM 2.0.
Thứ tự thiết lập trên màn hình xem tại SSO và SCIM.
Trong bảng dưới đây, {API} là địa chỉ API của Keural trong môi trường bạn sử dụng (ví dụ: https://api.keural.ai). Lấy giá trị chính xác từ địa chỉ hiển thị trong Quản lý tổ chức → Cài đặt SSO.
Tóm tắt các giá trị đăng ký
| Mục | Giá trị |
|---|---|
| URI chuyển hướng OIDC | {API}/api/sso/callback |
| Bắt đầu đăng nhập OIDC·SAML | {API}/api/sso/{orgId}/login |
| EntityID của SP SAML | {API}/api/sso/saml/metadata |
| URL ACS SAML | {API}/api/sso/saml/callback |
| URL cơ sở SCIM | {API}/scim/v2 |
Đăng nhập luôn bắt đầu từ phía Keural (SP-initiated). Khi bạn nhập email của một tên miền đã đăng ký trên màn hình đăng nhập, bạn sẽ được chuyển đến địa chỉ bắt đầu đăng nhập. Nếu đăng nhập thành công, bạn quay lại màn hình đầu của Keural; nếu thất bại, bạn được đưa về /login?error=sso.
OIDC
| Mục | Hành vi |
|---|---|
| Luồng | Authorization Code |
| Yêu cầu authorize | response_type=code, client_id, redirect_uri, scope=openid email profile, state, nonce |
| state · nonce | Dùng một lần và có hiệu lực trong 10 phút. Nếu cửa sổ đăng nhập mở quá 10 phút, bạn cần đăng nhập lại từ đầu. |
| Đổi token | POST tới token endpoint, application/x-www-form-urlencoded. Xác thực client là client_secret_post (client_id và client_secret nằm trong body). |
| Chữ ký ID token | Chỉ chấp nhận RS256. Khóa được tìm trong jwks_uri theo kid. |
| Kiểm tra ID token | Chữ ký, exp, aud chứa client_id, nonce khớp, và iss trùng với Issuer URL (bỏ qua dấu / ở cuối). |
Claim email của ID token. Nếu không có, hệ thống gọi userinfo endpoint với Authorization: Bearer <access_token> và đọc email từ đó. | |
| Tên | Claim name của ID token |
| Endpoint | Tìm trong /.well-known/openid-configuration của Issuer URL. Nếu IdP không có, hãy nhập thủ công địa chỉ authorization, token, JWKS và userinfo trong Mở cài đặt nâng cao. |
| Thời gian chờ | 15 giây cho mỗi lần gọi IdP |
Ứng dụng trên IdP phải cho phép client_secret_post. Nếu cấu hình chỉ cho phép client_secret_basic hoặc private_key_jwt, việc đổi token sẽ thất bại.
SAML 2.0
| Mục | Hành vi |
|---|---|
| Yêu cầu | Gửi AuthnRequest qua binding HTTP-Redirect. Yêu cầu không được ký. |
| Nội dung yêu cầu | Destination=URL SSO của IdP, AssertionConsumerServiceURL=URL ACS, ProtocolBinding=HTTP-POST, Issuer=EntityID của SP, NameIDPolicy Format=…:nameid-format:unspecified, AllowCreate=true |
| Phản hồi | Binding HTTP-POST với SAMLResponse và RelayState. RelayState phải được trả lại đúng như Keural đã gửi. |
| Chữ ký | Response hoặc Assertion phải có chữ ký hợp lệ. Khóa xác minh chỉ là chứng chỉ đã đăng ký trên màn hình. |
| Assertion | Phản hồi phải chứa đúng một assertion. Không chấp nhận assertion được mã hóa (EncryptedAssertion). |
| Trạng thái | StatusCode là urn:oasis:names:tc:SAML:2.0:status:Success |
| Issuer | Nếu bạn đã nhập EntityID của IdP, giá trị này phải khớp với Issuer của assertion |
| Điều kiện | NotBefore và NotOnOrAfter (sai số cho phép 300 giây), Audience=EntityID của SP |
| SubjectConfirmationData | Recipient=URL ACS, NotOnOrAfter (sai số cho phép 300 giây), InResponseTo=ID của yêu cầu mà Keural đã gửi |
Thuộc tính có Name hoặc FriendlyName là một trong các giá trị sau (không phân biệt hoa thường): email, mail, emailAddress, E-Mail-Addresses, http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress. Nếu không có, hệ thống dùng NameID có chứa @. | |
| Tên | displayName, name, cn, http://schemas.microsoft.com/identity/claims/displayname |
| Chứng chỉ | Một chứng chỉ X.509. Định dạng PEM hoặc Base64 (DER). Khi thay chứng chỉ, hãy nhập chứng chỉ mới và lưu. |
| Metadata | Thay vì tải lên XML metadata của IdP, hãy nhập ba giá trị: EntityID của IdP, URL SSO của IdP và chứng chỉ. |
Xác định người dùng
| Mục | Hành vi |
|---|---|
| Điều kiện chuyển sang SSO | Phần sau @ của email trùng chính xác với một mục trong danh sách tên miền email (không phân biệt hoa thường). Tên miền phụ phải đăng ký riêng. |
| Tìm tài khoản | Tìm tài khoản Keural theo email (chữ thường) do IdP gửi. |
| Khi chưa có tài khoản | Nếu Tự động tạo người dùng khi đăng nhập lần đầu (JIT) được bật, tài khoản sẽ được tạo; nếu tắt, đăng nhập bị từ chối. |
| Tham gia tổ chức | Nếu chưa là thành viên tổ chức, người dùng được thêm với vai trò Thành viên. Nếu hết chỗ hoặc tài khoản thuộc tổ chức khác, người dùng không được thêm và chỉ có thể đăng nhập. |
| Điều kiện lưu tên miền email | Tên miền đã xác minh bằng TXT trên DNS, trừ các tên miền email công cộng |
Xác minh tên miền
| Mục | Giá trị |
|---|---|
| Loại bản ghi | TXT |
| Host | Tên miền đã đăng ký, giữ nguyên (ví dụ: acme.com). Không dùng tên miền phụ có tiền tố. |
| Giá trị | keural-verify=<UUID>, đúng như hiển thị trên màn hình |
| Thời điểm kiểm tra | Kiểm tra một lần khi bạn nhấn Xác nhận xác minh. |
SCIM 2.0
| Mục | Giá trị |
|---|---|
| URL cơ sở | {API}/scim/v2 |
| Xác thực | Authorization: Bearer <token SCIM>. Token bắt đầu bằng scim_ và chỉ hiển thị một lần khi được cấp. |
| Content-Type | Yêu cầu application/scim+json hoặc application/json; phản hồi application/scim+json |
| Mã trạng thái | Trả về đúng mã HTTP thực tế. Nội dung lỗi theo định dạng SCIM Error (schemas, status, detail, scimType). |
Endpoint
| Phương thức | Đường dẫn | Hành vi |
|---|---|---|
GET | /Users | Danh sách. filter=userName eq "…", startIndex (mặc định 1), count (mặc định 100, tối đa 200) |
GET | /Users/{id} | Xem một người dùng |
POST | /Users | Tạo mới (201). Nếu email đã tồn tại, trả về 409. |
PATCH | /Users/{id} | Thay đổi active, displayName, name.formatted, name.givenName |
PUT | /Users/{id} | Áp dụng displayName, name và active. Nếu bỏ qua active, người dùng được coi là đang hoạt động. |
DELETE | /Users/{id} | Tạm khóa tài khoản (204). Không xóa dữ liệu. |
GET | /Groups, /Groups/{id} | Xem hai nhóm cố định. filter=displayName eq "…" |
PATCH | /Groups/{id} | Thêm, gỡ hoặc thay thế thành viên |
GET | /ServiceProviderConfig, /ResourceTypes, /Schemas | Xem các tính năng được hỗ trợ |
Thuộc tính người dùng
| Thuộc tính | Công dụng |
|---|---|
userName | Email. Nếu không có, dùng emails[0].value. |
displayName · name.formatted · name.givenName+name.familyName | Tên hiển thị |
active | false tạm khóa (chặn đăng nhập); true khôi phục |
id | ID người dùng Keural. Được trả về trong phản hồi. |
Hệ thống không lưu externalId. Để tìm người dùng từ IdP, hãy dùng bộ lọc userName.
Nhóm
| id | displayName | Khi thêm thành viên | Khi gỡ thành viên |
|---|---|---|---|
keural-admins | Keural Admins | Quản trị viên | Thành viên |
keural-members | Keural Members | Thành viên | Không thay đổi |
Vai trò chủ sở hữu tổ chức không bị thay đổi bởi SCIM. Tạo và xóa nhóm (POST·DELETE /Groups) trả về 501. Giá trị value của thành viên nhóm là ID người dùng Keural (id trong /Users).
Phạm vi hỗ trợ
| Tính năng | Hỗ trợ |
|---|---|
| PATCH | Có |
| Bộ lọc | userName eq, displayName eq |
| Bulk · sắp xếp · ETag · đổi mật khẩu | Không |
Lỗi
| Trạng thái | scimType | Nguyên nhân |
|---|---|---|
400 | invalidValue | Thiếu cả userName và emails |
401 | — | Thiếu hoặc sai token, hoặc tính năng cấp phát SCIM đang tắt |
404 | — | Người dùng hoặc nhóm không thuộc tổ chức này |
409 | uniqueness | Đã có tài khoản với cùng email, hoặc vượt quá số ghế |
501 | — | Tạo hoặc xóa nhóm |