Authagonal
Tài liệu
Mọi thứ bạn cần để bắt đầu với Authagonal — từ việc tạo tenant đầu tiên đến thiết lập SSO, SCIM và thương hiệu tùy chỉnh.
Bắt đầu
Authagonal cung cấp cho mỗi tenant một máy chủ OIDC tuân thủ đầy đủ tiêu chuẩn. Mỗi tenant có URL issuer riêng, tài liệu discovery và các điểm cuối token — không chia sẻ hạ tầng giữa các tenant. Bạn có thể từ số không đến luồng đăng nhập hoạt động trong chưa đầy 5 phút.
Tạo Tenant
Đăng ký tại authagonal.io và chọn một slug cho tenant. Slug trở thành tên miền issuer: {slug}.authagonal.io. Sau khi tạo tài khoản, xác minh địa chỉ email để kích hoạt tenant.


Chọn một slug duy nhất cho tenant trong quá trình đăng ký
Đăng ký Client
Điều hướng đến Clients trong thanh bên cổng và nhấp Client mới. Nhập clientId và clientName cho ứng dụng của bạn. Sau đó, trên tab URIs của client, thêm ít nhất một URI chuyển hướng; đây là nơi người dùng được chuyển đến sau khi xác thực. Ví dụ: https://app.example.com/callback. Client mới mặc định yêu cầu client secret, vì vậy với ứng dụng trình duyệt không có backend, hãy tắt Yêu cầu Secret trên tab Chung.


Đăng ký ứng dụng OAuth mới trong cổng
Phát triển cục bộ
http://localhost:3000/callback làm URI chuyển hướng cho phát triển cục bộ. Authagonal cho phép URI chuyển hướng không HTTPS cho nguồn gốc localhost.Đăng nhập đầu tiên
Cách nhanh nhất để tích hợp là với oidc-client-ts, một thư viện OIDC nhẹ cho ứng dụng JavaScript và TypeScript.
import { UserManager } from 'oidc-client-ts';
const mgr = new UserManager({
authority: 'https://acme.authagonal.io',
client_id: 'my-app',
redirect_uri: 'https://app.example.com/callback',
response_type: 'code',
scope: 'openid profile email',
});
// Redirect to login
mgr.signinRedirect();
// On callback page
const user = await mgr.signinRedirectCallback();
console.log(user.profile); // { sub, email, name, ... }Nếu bạn muốn cách tiếp cận tối giản không cần thư viện, bạn có thể sử dụng luồng mã ủy quyền OAuth 2.0 tiêu chuẩn với fetch thuần:
// 1. Redirect the user to the authorization endpoint
const authorizeUrl = new URL('https://acme.authagonal.io/connect/authorize');
authorizeUrl.searchParams.set('client_id', 'my-app');
authorizeUrl.searchParams.set('redirect_uri', 'https://app.example.com/callback');
authorizeUrl.searchParams.set('response_type', 'code');
authorizeUrl.searchParams.set('scope', 'openid profile email');
authorizeUrl.searchParams.set('code_challenge', codeChallenge);
authorizeUrl.searchParams.set('code_challenge_method', 'S256');
window.location.href = authorizeUrl.toString();
// 2. On the callback page, exchange the code for tokens
const res = await fetch('https://acme.authagonal.io/connect/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
grant_type: 'authorization_code',
code: new URLSearchParams(window.location.search).get('code')!,
redirect_uri: 'https://app.example.com/callback',
client_id: 'my-app',
code_verifier: codeVerifier,
}),
});
const tokens = await res.json();
// tokens.id_token, tokens.access_token (refresh_token only when offline_access is requested and allowed)

Trang đăng nhập mặc định cho tenant của bạn
Chế độ Sandbox
{env}-{slug}.authagonal.io, ví dụ test1-acme.authagonal.io) và có thể được đặt lại về trạng thái trống bất cứ lúc nào mà không ảnh hưởng người dùng thực.Bảng điều khiển
Bảng điều khiển cổng cung cấp tổng quan thời gian thực về tenant. Nó hiển thị các chỉ số quan trọng nhất — tăng trưởng người dùng, hoạt động xác thực và điều hướng nhanh đến mọi tính năng trong cổng.
Tổng quan
Ở đầu bảng điều khiển, bạn sẽ thấy thông báo chào mừng và liên kết Mở trang đăng nhập tới trang đăng nhập được lưu trữ của tenant. Bên dưới các thẻ thống kê, đồng hồ đo Người dùng hoạt động hàng tháng theo dõi mức sử dụng so với giới hạn của gói và hiển thị liên kết tới các tùy chọn gói khi bạn vượt quá 80%. Biểu đồ Hoạt động đăng nhập và nguồn cấp Hoạt động gần đây gồm các mục nhật ký kiểm toán mới nhất hoàn thiện trang.


Màn hình chính bảng điều khiển với các thẻ thống kê và hoạt động đăng nhập
Chỉ số hoạt động
Sáu thẻ thống kê tóm tắt nhanh tình hình tenant của bạn:
- Người dùng hoạt động: tổng số người dùng trong tenant của bạn
- Đăng nhập (24h): số lần đăng nhập thành công trong 24 giờ qua
- Đã bật MFA: tỷ lệ phần trăm người dùng đã đăng ký MFA, kèm số người đã đăng ký và tổng số người dùng
- Lần thử thất bại (24h): số lần đăng nhập thất bại trong 24 giờ qua, chẳng hạn do thông tin đăng nhập sai, tài khoản bị khóa hoặc bị chính sách từ chối
- Đồng bộ SCIM: hoạt động cung cấp từ các IdP đã kết nối, hiển thị là Nhàn rỗi hoặc dưới dạng số lượng thao tác
- Chi tiêu hàng tháng: chi tiêu tính đến nay trong tháng này, kèm con số dự kiến vào cuối tháng
Các thẻ 24 giờ so sánh 24 giờ qua với 24 giờ trước đó. Biểu đồ Hoạt động đăng nhập thể hiện số lần đăng nhập thành công và thất bại mỗi ngày trong 14, 30 hoặc 90 ngày. Bảng điều khiển tự làm mới mỗi phút.


Các thẻ thống kê tóm tắt 24 giờ qua
Điều hướng nhanh
Bên dưới các chỉ số, các thẻ điều hướng liên kết trực tiếp đến Clients, SSO, Người dùng, SCIM, Thương hiệu, Cài đặt, Thanh toán, Tên miền và Nhật ký kiểm tra. Mỗi thẻ hiển thị mô tả ngắn để thành viên mới nhanh chóng nắm bắt.
Ứng dụng
Các OAuth client đại diện cho ứng dụng xác thực người dùng qua tenant. Mỗi client có cấu hình riêng cho URI chuyển hướng, phạm vi, loại cấp quyền, thời hạn token và chính sách MFA.
Danh sách Client
Trang Ứng dụng hiển thị bảng tất cả client đã đăng ký. Mỗi hàng hiển thị clientId, tên hiển thị, các loại cấp quyền được phép dưới dạng huy hiệu màu và trạng thái PKCE. Nhấp vào bất kỳ hàng nào để mở trình chỉnh sửa cấu hình đầy đủ.


Danh sách client với huy hiệu loại cấp quyền và chỉ báo PKCE
Tạo Client
Nhấp Client mới để đăng ký ứng dụng mới. Bạn cần cung cấp hai trường:
clientId— mã định danh duy nhất cho client (ví dụ:my-spa)clientName— tên hiển thị dễ đọc


Đăng ký ứng dụng OAuth mới
Xóa Client
Để xóa một client, nhấp biểu tượng thùng rác trên hàng của client đó trong bảng clients và nhập ID client để xác nhận. Client bị xóa vĩnh viễn và không thể đăng nhập người dùng hay làm mới token nữa. Các access token đã cấp không bị thu hồi và vẫn có hiệu lực cho đến khi hết hạn.
Tham chiếu cấu hình Client
Mỗi client có bộ tùy chọn cấu hình toàn diện được tổ chức thành năm tab: Chung, URIs, Scopes & Grants, Tokens và Bảo mật.
Cài đặt chung
| Cài đặt | Mô tả | Mặc định |
|---|---|---|
clientName | Tên hiển thị trên màn hình đồng ý và trong cổng | – |
requirePkce | Yêu cầu Proof Key for Code Exchange trên luồng mã ủy quyền | Bật |
requireClientSecret | Yêu cầu client secret cho yêu cầu token (tắt cho client công khai như SPA) | Bật |
allowOfflineAccess | Cho phép client yêu cầu refresh token qua phạm vi offline_access | Tắt |
alwaysIncludeUserClaimsInIdToken | Bao gồm các claim hồ sơ, email, vai trò và nhóm trong ID token ngay cả khi các scope tương ứng không được yêu cầu | Tắt |
includeGroupsInTokens | Bao gồm tên các nhóm SCIM của người dùng dưới dạng claim groups trong các token được cấp khi scope groups được yêu cầu | Tắt |
Bảo mật PKCE
URI
Các trường URI sử dụng nhập thẻ — nhập giá trị và nhấn Enter hoặc dấu phẩy để thêm. Nhấp X trên bất kỳ thẻ nào để xóa.
| Cài đặt | Mô tả |
|---|---|
redirectUris | URL callback được phép sau khi xác thực. Phải khớp chính xác với tham số redirect_uri trong yêu cầu ủy quyền. |
postLogoutRedirectUris | URL được phép chuyển hướng đến sau khi đăng xuất. |
allowedCorsOrigins | Nguồn gốc được phép cho yêu cầu cross-origin đến điểm cuối token và UserInfo. |


Trường nhập thẻ để cấu hình URI
Phạm vi & Loại cấp quyền
| Cài đặt | Tùy chọn |
|---|---|
allowedScopes | openid profile email offline_access phone roles groups |
allowedGrantTypes | authorization_code client_credentials refresh_token urn:ietf:params:oauth:grant-type:device_code urn:ietf:params:oauth:grant-type:token-exchange |
Thời hạn Token
| Cài đặt | Mô tả | Mặc định |
|---|---|---|
accessTokenLifetimeSeconds | Thời gian access token có hiệu lực | 1800 (30 phút) |
identityTokenLifetimeSeconds | Thời gian ID token có hiệu lực | 300 (5 phút) |
authorizationCodeLifetimeSeconds | Thời gian mã ủy quyền có hiệu lực để trao đổi | 300 (5 phút) |
absoluteRefreshTokenLifetimeSeconds | Thời hạn tối đa của refresh token bất kể hoạt động | 2592000 (30 ngày) |
slidingRefreshTokenLifetimeSeconds | Thời hạn refresh token được đặt lại mỗi lần sử dụng, tối đa đến thời hạn tuyệt đối | 1296000 (15 ngày) |


Cấu hình thời hạn token theo từng client
URI đăng xuất
Client có thể đăng ký cả URI đăng xuất back-channel và front-channel. Cả hai đều tùy chọn — cấu hình loại phù hợp với cách ứng dụng của bạn xóa phiên.
| Cài đặt | Mô tả |
|---|---|
backChannelLogoutUri | POST server-đến-server với logout token đã ký. Tin cậy ngay cả khi trình duyệt người dùng offline. |
frontChannelLogoutUri | Được tải trong iframe ẩn khi đăng xuất để trình duyệt xóa cookie và local storage. |
frontChannelLogoutSessionRequired | Khi bật, URL đăng xuất nhận các tham số iss và sid để ứng dụng của bạn có thể liên kết đăng xuất với phiên cụ thể. |
Dùng cả hai cùng nhau
Chính sách MFA
Mỗi client có chính sách MFA riêng, được đặt trên tab <strong>Bảo mật</strong> của client. Menu thả xuống chính sách MFA cung cấp ba tùy chọn:
| Chính sách | Hành vi |
|---|---|
| Tắt | MFA không bao giờ được yêu cầu cho client này |
| Bật | Người dùng có thể tùy chọn đăng ký MFA; họ sẽ được yêu cầu nếu đã đăng ký |
| Bắt buộc | Tất cả người dùng phải hoàn thành MFA để xác thực qua client này |


Chính sách MFA theo từng client
SSO doanh nghiệp
SSO doanh nghiệp cho phép khách hàng sử dụng nhà cung cấp danh tính riêng. Authagonal hỗ trợ cả liên kết SAML 2.0 và OIDC với định tuyến theo tên miền, để người dùng tự động được chuyển đến IdP chính xác dựa trên địa chỉ email.
Định tuyến SSO theo tên miền
Kết nối SAML 2.0
Để tạo kết nối SAML, điều hướng đến trang SSO và chọn tab SAML. Cung cấp các thông tin sau:
| Trường | Mô tả |
|---|---|
connectionName | Tên dễ đọc cho kết nối này (ví dụ: "Acme Corp Okta") |
entityId | ID thực thể SP của bạn. Đăng ký chính xác giá trị này tại IdP làm Identifier (Entity ID) của ứng dụng; các assertion phải ghi nó làm Audience |
metadataLocation | URL tới tài liệu XML metadata SAML của IdP |
metadataXml | XML metadata của IdP được dán vào, dành cho IdP không có URL metadata (Google Workspace) hoặc URL không truy cập được từ internet. Cung cấp trường này hoặc metadataLocation, không phải cả hai |
nameIdFormat | Định dạng NameID tùy chọn yêu cầu từ IdP. Bỏ trống để dùng mặc định emailAddress, hoặc đặt "none" để bỏ hẳn NameIDPolicy (khuyến nghị cho ADFS) |
allowedDomains | Các tên miền email được định tuyến tới kết nối này (ví dụ: acme.com). Đặt qua API; cổng hiển thị chúng trên thẻ kết nối và trên tab Định tuyến tên miền |
Khi bạn lưu kết nối, Authagonal tải tài liệu metadata và nhập chứng chỉ ký của IdP, URL điểm cuối SSO và định dạng mã định danh. Metadata được làm mới định kỳ để cập nhật xoay chứng chỉ.


Tạo kết nối SSO SAML 2.0
Kết nối OIDC
Để tạo kết nối liên kết OIDC, chọn tab OIDC và cung cấp:
| Trường | Mô tả |
|---|---|
connectionName | Tên dễ đọc cho kết nối này |
metadataLocation | URL discovery OpenID Connect (ví dụ: https://login.microsoftonline.com/{tenant}/v2.0/.well-known/openid-configuration) |
clientId | Client ID đã đăng ký với IdP bên ngoài cho liên kết này |
clientSecret | Client secret cho đăng ký IdP bên ngoài |
allowedDomains | Các tên miền email được định tuyến tới kết nối này (ví dụ: acme.com). Đặt qua API; cổng hiển thị chúng trên thẻ kết nối và trên tab Định tuyến tên miền |


Tạo kết nối liên kết OIDC
Định tuyến tên miền
Định tuyến tên miền tự động chuyển hướng người dùng đến nhà cung cấp danh tính chính xác dựa trên tên miền email. Khi người dùng nhập email trên trang đăng nhập, Authagonal kiểm tra phần tên miền (ví dụ: acme.com) có khớp với allowedDomains của bất kỳ kết nối SSO nào không. Nếu khớp, người dùng được chuyển hướng liền mạch đến IdP của tổ chức họ.
| Tên miền Email | Nhà cung cấp SSO | Giao thức |
|---|---|---|
| acme.com | Acme Corp Okta | SAML 2.0 |
| contoso.com | Contoso Azure AD | OIDC |
| example.org | Example OneLogin | SAML 2.0 |


Định tuyến tên miền ánh xạ tên miền email đến nhà cung cấp danh tính
Luồng khởi tạo từ SP
/saml/{connectionId}/login hoặc /oidc/{connectionId}/login.Cung cấp JIT
Khi người dùng đăng nhập qua SSO lần đầu và chưa tồn tại trong tenant, Authagonal có thể tự động tạo tài khoản (cung cấp Just-In-Time). Cung cấp JIT mặc định bị tắt: hãy bật cho từng kết nối bằng cách chọn Bật cấp tài khoản JIT khi tạo kết nối.
Khi cung cấp JIT bị tắt, chỉ người dùng đã được cung cấp trước — qua SCIM, trang Người dùng của cổng hoặc API — mới có thể đăng nhập qua kết nối đó. Người dùng không xác định nhận lỗi access_denied và được hướng dẫn liên hệ quản trị viên.
Cài đặt theo kết nối
Kiểm tra trước khi triển khai
Kết nối theo phạm vi tổ chức
Một kết nối cũng có thể thuộc về một tổ chức trong tenant của bạn thay vì toàn bộ tenant. Kết nối chỉ được đề xuất khi tổ chức đó đã được xác định, thông qua tên miền tùy chỉnh được ghim vào tổ chức, tham số organization trên liên kết đăng nhập, hoặc một client đã đăng ký cho đúng tổ chức đó, và không bao giờ xuất hiện trên trang đăng nhập áp dụng cho cả tenant. Thứ tự ưu tiên khi xác định được kiểm tra theo đúng thứ tự trên, từ cao đến thấp.
Đăng nhập sẽ tạo tư cách thành viên
Tên miền là duy nhất theo từng phạm vi
acme.com có thể được định tuyến đến một kết nối áp dụng cho cả tenant, và cũng đến kết nối riêng của tổ chức khi tổ chức đã được chọn. Điều không thể xảy ra là một tên miền thuộc về hai kết nối trong cùng một phạm vi; Authagonal sẽ từ chối khi bạn lưu kết nối.Người dùng
Trang Người dùng cho phép bạn quản lý tất cả người dùng cuối trong tenant. Bạn có thể tìm kiếm người dùng, xem chi tiết, mời người dùng mới và xem cách mỗi người dùng được cung cấp.
Tìm kiếm & Phân trang
Thanh tìm kiếm khớp chính xác với ID người dùng hoặc email, hoặc với tiền tố của email, tên hoặc họ, và các bộ lọc Tất cả, Hoạt động và Không hoạt động thu hẹp danh sách theo trạng thái. Tìm kiếm được debounce ở 300ms nên kết quả cập nhật khi bạn gõ mà không làm quá tải API. Kết quả được phân trang 50 người dùng mỗi trang; sử dụng điều khiển điều hướng ở cuối bảng để chuyển trang.
Bảng người dùng
Bảng người dùng hiển thị các cột sau cho mỗi người dùng:
| Cột | Mô tả |
|---|---|
| Người dùng | Tên của người dùng (hoặc email khi chưa đặt tên), với email bên dưới và huy hiệu Chưa xác minh cho đến khi email được xác nhận |
| Trạng thái | Active hoặc Inactive — cho biết tài khoản có được bật hay không |
| Nguồn | SCIM hoặc Local — cách người dùng được tạo |
| Vai trò | Các vai trò được gán cho người dùng |
| MFA | Enabled khi đã đăng ký xác thực đa yếu tố, nếu chưa thì hiển thị dấu gạch ngang |
| Ngày tạo | Ngày tài khoản người dùng được tạo |


Danh sách người dùng với thanh tìm kiếm và phân trang
Mời người dùng
Nhấp Mời người dùng để mời ai đó vào tenant của bạn. Họ sẽ nhận được email để tự đặt mật khẩu. Biểu mẫu gồm:
| Trường | Mô tả |
|---|---|
email | Địa chỉ email của người dùng (phải là duy nhất trong tenant) |
firstName | Tên của người dùng |
lastName | Họ của người dùng |
locale | Ngôn ngữ ưu tiên. Đặt ngôn ngữ giao diện và e-mail của người dùng; tuỳ chọn, mặc định về tiếng Anh. |
organizationId | Tổ chức tùy chọn để thêm người dùng vào, kèm vai trò của họ trong tổ chức đó. Hiển thị khi tenant của bạn có tổ chức |


Mời người dùng mới
Người dùng được cung cấp qua SCIM
Ngôn ngữ ưu tiên
Mỗi người dùng có một ngôn ngữ ưu tiên điều khiển cả giao diện được lưu trữ lẫn các e-mail giao dịch mà Authagonal gửi cho họ (xác minh, đặt lại mật khẩu, chào mừng và nhiều hơn nữa). Bạn có thể đặt ngôn ngữ này khi mời người dùng và thay đổi bất cứ lúc nào từ trang chi tiết của người dùng. Nếu người dùng chưa đặt ngôn ngữ ưu tiên, Authagonal sẽ mặc định về tiếng Anh. Bộ chọn cung cấp tất cả các ngôn ngữ được hỗ trợ: tiếng Anh, tiếng Trung (giản thể), tiếng Đức, tiếng Pháp, tiếng Tây Ban Nha, tiếng Việt, tiếng Bồ Đào Nha, tiếng Nhật, tiếng Ả Rập, tiếng Hindi và tiếng Afrikaans.


Đặt ngôn ngữ ưu tiên của người dùng trên trang chi tiết
Chi tiết người dùng
Nhấp vào bất kỳ hàng nào trong danh sách người dùng để mở trang chi tiết. Từ đó, bạn có thể chỉnh sửa hồ sơ, quản lý vai trò, đặt lại MFA, xem thuộc tính tùy chỉnh và xóa người dùng.


Hồ sơ
Chỉnh sửa email, họ/tên, điện thoại, công ty, ngôn ngữ, ID bên ngoài và trạng thái hoạt động của người dùng. Việc thay đổi email hoặc cờ xác nhận email cần vai trò Admin hoặc Owner. Thay đổi email phải giữ tính duy nhất trong tenant; API trả về email_already_in_use nếu đã được sử dụng.
Vai trò
Gán và gỡ vai trò được định nghĩa trên trang Vai trò. Các vai trò đã gán được phát ra dưới dạng claim roles trong ID token và access token khi client yêu cầu scope roles.
Xác thực đa yếu tố
Xem mọi thông tin xác thực MFA đã đăng ký cho người dùng (ứng dụng xác thực (TOTP), WebAuthn/passkey và mã khôi phục), mỗi cái có dấu thời gian đăng ký và sử dụng gần nhất. Xóa thông tin xác thực riêng lẻ hoặc đặt lại tất cả MFA; cả hai đều cần vai trò Admin hoặc Owner. Đặt lại buộc người dùng đăng ký lại khi đăng nhập tiếp theo.
Thuộc tính tùy chỉnh
Dữ liệu khóa/giá trị tùy ý gắn với người dùng. Khóa phải là duy nhất. Thuộc tính được phơi bày qua API hồ sơ người dùng và SCIM, và có thể được ánh xạ thành claim của access token bằng cách cấu hình userClaims của scope tùy chỉnh.
Tổ chức
Tổ chức mà người dùng này thuộc về. Đây là một định danh dạng văn bản tự do của riêng bạn, được phát ra dưới dạng claim org_id trên token của họ và trên /connect/userinfo với scope profile. Authagonal không bao giờ tự suy ra giá trị này: nó được đặt bởi ứng dụng cung cấp của bạn, bởi thông tin xác thực SCIM đã tạo ra người dùng, hoặc đặt thủ công tại đây.
Liên kết bên cạnh trường này liệt kê tất cả những ai dùng chung giá trị đó, và cùng bộ lọc ấy có sẵn trên API dưới dạng GET /api/v1/users?organizationId=. Hãy dùng nó để trả lời ai thuộc về một khách hàng cụ thể mà không phải phân trang toàn bộ thư mục.
Xóa người dùng
Xóa vĩnh viễn người dùng và tất cả thông tin xác thực MFA của họ. Nhập email người dùng để xác nhận — không thể hoàn tác.
Nhóm
Nhóm cho phép bạn tổ chức người dùng và bao gồm thành viên nhóm trong token. Nhóm có thể được tạo thủ công trong cổng hoặc cung cấp tự động qua SCIM từ nhà cung cấp danh tính bên ngoài.
Danh sách nhóm
Các nhóm được liệt kê trên tab Nhóm của trang SCIM, với thông tin sau:
| Cột | Mô tả |
|---|---|
| Tên nhóm | Tên hiển thị của nhóm |
| Thành viên | Số lượng người dùng hiện tại trong nhóm |
| Nguồn | SCIM hoặc Manual — cách nhóm được tạo |
| Ngày tạo | Ngày nhóm được tạo |


Danh sách nhóm với chỉ báo nguồn
Tạo nhóm
Nhấp Nhóm mới và nhập Tên hiển thị cho nhóm. Tên nhóm nên mô tả rõ ràng và duy nhất trong tenant (ví dụ: "Engineering", "Billing Admins", "Beta Testers").
Chi tiết nhóm & Thành viên
Nhấp vào bất kỳ nhóm nào để mở xem chi tiết. Tại đây bạn có thể xem tất cả thành viên hiện tại và quản lý thành viên:
- Thêm thành viên: tìm người dùng theo email hoặc tên và thêm họ vào nhóm.
- Xóa thành viên: nhấp nút xóa bên cạnh bất kỳ thành viên nào và xác nhận. Mọi vai trò được cấp thông qua nhóm sẽ bị thu hồi.


Quản lý thành viên nhóm trong xem chi tiết
Nhóm trong Token
Khi Nhóm trong Tokens được bật trên một client và scope groups được yêu cầu, các token được cấp sẽ bao gồm claim groups liệt kê tên hiển thị của các nhóm mà người dùng thuộc về:
{
"sub": "user-123",
"email": "[email protected]",
"groups": ["Engineering", "Beta Testers"]
}Bật theo từng Client
groups.Vai trò
Vai trò hỗ trợ kiểm soát truy cập dựa trên vai trò (RBAC) trong ứng dụng. Định nghĩa vai trò trong Authagonal, gán cho người dùng và sử dụng claim roles trong token để thực thi ủy quyền trong logic ứng dụng.
Quản lý vai trò
Trang Vai trò hiển thị bảng tất cả vai trò đã định nghĩa với chỉnh sửa trực tiếp. Mỗi vai trò có:
| Cột | Mô tả |
|---|---|
| Tên | Mã định danh duy nhất cho vai trò (ví dụ: "admin", "editor", "viewer") |
| Mô tả | Mô tả dễ đọc về những gì vai trò cấp quyền |
| Ngày tạo | Ngày vai trò được tạo |
Tạo vai trò
Nhấp Vai trò mới và cung cấp tên và mô tả. Tên vai trò nên ngắn gọn và tuân theo quy ước đặt tên nhất quán trong ứng dụng (ví dụ: chữ thường với gạch ngang: billing-admin).
Chỉnh sửa trực tiếp
Vai trò hỗ trợ chỉnh sửa trực tiếp trong bảng. Nhấp biểu tượng bút chì trên bất kỳ vai trò nào để vào chế độ chỉnh sửa — các trường tên và mô tả trở nên chỉnh sửa được. Sửa đổi giá trị, sau đó nhấp biểu tượng dấu kiểm để lưu. Thay đổi có hiệu lực ngay lập tức.
Xóa vai trò
Nhấp biểu tượng xóa trên bất kỳ vai trò nào để xóa. Bạn sẽ được yêu cầu xác nhận trước khi vai trò bị xóa vĩnh viễn. Xóa vai trò không vô hiệu hóa hồi tố các token hiện có — vai trò sẽ vắng mặt trong token mới được phát hành sau khi xóa.


Chỉnh sửa trực tiếp vai trò trong bảng vai trò
Vai trò trong Token
Vai trò được gán cho người dùng được bao gồm dưới dạng claim roles trong ID token và access token khi client yêu cầu scope roles. Ứng dụng có thể đọc claim này để đưa ra quyết định ủy quyền:
{
"sub": "user-123",
"email": "[email protected]",
"roles": ["admin", "billing-admin"]
}Cung cấp SCIM
SCIM 2.0 (System for Cross-domain Identity Management) cho phép cung cấp người dùng và nhóm tự động từ các nhà cung cấp danh tính doanh nghiệp như Okta, Azure AD, OneLogin và JumpCloud. Khi được cấu hình, tài khoản người dùng và thành viên nhóm tự động được đồng bộ từ IdP upstream đến tenant Authagonal của bạn.
Đồng bộ vòng đời người dùng SCIM với cung cấp downstream
Các bước thiết lập
Làm theo các bước sau để bật cung cấp SCIM cho một client:
- Chọn ứng dụng client — Chọn OAuth client mà cung cấp SCIM sẽ được liên kết.
- Tạo token SCIM — Cung cấp mô tả và thời hạn tính bằng ngày, sau đó tạo token.
- Sao chép token ngay — Giá trị token thô chỉ hiển thị một lần. Sao chép trước khi đóng hộp thoại.
- Cấu hình IdP — Trong cài đặt SCIM của nhà cung cấp danh tính, nhập URL cơ sở và bearer token.
- Kiểm tra đồng bộ người dùng — Kích hoạt đồng bộ thử từ IdP và xác minh người dùng xuất hiện trong cổng Authagonal.
URL cơ sở SCIM
Cấu hình nhà cung cấp danh tính với URL cơ sở sau:
https://{slug}.authagonal.io/scim/v2Thay thế {slug} bằng slug tenant của bạn.


Trang thiết lập SCIM với tạo token
Quản lý Token
Token SCIM xác thực các yêu cầu cung cấp từ IdP. Bạn có thể quản lý nhiều token cho mỗi client:
| Trường | Mô tả |
|---|---|
| Mô tả | Nhãn để nhận dạng token (ví dụ: "Okta Production SCIM") |
| Hạn sử dụng | Thời hạn token tính bằng ngày (1 đến 3650, mặc định 365). |
| Trạng thái | Token đang hoạt động đang được sử dụng. Token bị thu hồi hiển thị Revoked huy hiệu và không còn có thể xác thực yêu cầu. |
Để thu hồi token, nhấp nút Thu hồi bên cạnh. Token bị thu hồi vẫn hiển thị trong danh sách cho mục đích kiểm toán nhưng ngay lập tức ngừng chấp nhận yêu cầu.


Quản lý token với chỉ báo token đang hoạt động và đã thu hồi
Sao chép Token ngay
Kiểm tra kết nối
Xác minh tích hợp SCIM hoạt động bằng cách truy vấn điểm cuối ServiceProviderConfig:
curl -H "Authorization: Bearer YOUR_TOKEN" \ https://acme.authagonal.io/scim/v2/ServiceProviderConfig
Phản hồi thành công trả về tài liệu JSON mô tả các tính năng SCIM được hỗ trợ: PATCH và lọc được hỗ trợ, còn hoạt động hàng loạt, đổi mật khẩu, sắp xếp và ETag thì không.
Ngôn ngữ ưu tiên
preferredLanguage (mặc định về locale) được ánh xạ tới ngôn ngữ đã lưu của người dùng. Người dùng SSO được cung cấp qua SCIM tự động nhận được e-mail bản địa hoá bằng ngôn ngữ mà IdP của họ gửi.Những gì một thông tin xác thực có thể thấy
Một thông tin xác thực SCIM chỉ thấy những người dùng và nhóm do chính nó cung cấp. Việc đọc, cập nhật hay xóa một người dùng do connector khác tạo sẽ trả về 404, thao tác liệt kê chỉ trả về những gì của chính nó, và thành viên của một nhóm chỉ có thể là những người dùng do cùng connector đó cung cấp. Các tài khoản được tạo bằng bất kỳ cách nào khác, bởi quản trị viên, qua đăng ký tự phục vụ hay qua cung cấp just-in-time bằng SSO, hoàn toàn không nhìn thấy được đối với SCIM.
Ranh giới đó là theo client, không theo token. Hai thông tin xác thực được cấp trên cùng một client là một danh tính với hai secret, và mỗi cái đều có thể sửa những gì cái kia tạo ra. Hãy cấp cho các connector không tin cậy lẫn nhau mỗi bên một client riêng. externalId cũng có phạm vi như vậy, nên hai connector đều có thể dùng ext-001 cho hai người khác nhau mà không xung đột.
Hủy cung cấp
DELETE /scim/v2/Users/{id} vô hiệu hóa tài khoản và đánh dấu là đã xóa. Bản ghi vẫn được giữ lại, đúng như RFC 7644 cho phép, nhưng trả về 404 cho mọi thao tác sau đó và bị bỏ khỏi các danh sách. Các đăng ký MFA và thành viên nhóm của họ bị xóa, ánh xạ externalId được giải phóng, và mọi token đã cấp đều bị thu hồi, nên quyền truy cập chấm dứt ngay lập tức chứ không phải vào lần hết hạn token kế tiếp.
Nếu chính người đó sau này được tuyển lại và tạo lại, họ nhận một id người dùng mới. Định danh không bao giờ được tái sử dụng: id chính là subject trong mọi token bạn từng cấp, nên dùng lại nó sẽ âm thầm trao cho người mới vào toàn bộ lịch sử của người giữ trước đó tại mọi ứng dụng tin cậy id ấy.
Gắn thẻ tổ chức cho người dùng đã đồng bộ
SCIM không có cách nào để một connector cho biết nó đang đồng bộ khách hàng nào của bạn. SCIM lõi không định nghĩa thuộc tính tổ chức, nên một thao tác tạo người dùng thông thường chỉ cho bạn biết tên và email của người đó, không cho biết họ thuộc về ai. Nếu nhiều khách hàng cùng cung cấp người dùng vào tenant của bạn, người dùng của họ đến nơi mà không phân biệt được.
Chính thông tin xác thực trả lời câu hỏi đó, chứ không phải bản thân yêu cầu. Khi tạo một token SCIM, hãy chọn một trong các tổ chức của tenant ở mục Tổ chức (bộ chọn xuất hiện khi tenant của bạn đã có tổ chức). Mọi người dùng được cung cấp qua token đó đều trở thành thành viên đang hoạt động của tổ chức đó, và từ đó mang nó dưới dạng claim org_id trên token của họ. Hãy cấp một thông tin xác thực cho mỗi khách hàng trên cùng một client, và người dùng đã đồng bộ của họ sẽ được quy thuộc chính xác mà không cần đăng ký riêng một client cho từng khách hàng. Để trống thì người dùng không được gắn thẻ.
Gắn thẻ không phải là cô lập
Thẻ được gắn khi người dùng được tạo và không bao giờ ở lần cập nhật sau, nên một lần đồng bộ tăng dần thông thường không thể âm thầm chuyển một tài khoản đã tồn tại sang tổ chức khác. Nếu bạn còn chạy một ứng dụng cung cấp, thẻ đặt tường minh trên thông tin xác thực sẽ thắng: phản hồi /try chỉ điền vào tổ chức nào vẫn còn trống.
Các schema được hỗ trợ
Chúng tôi triển khai các schema lõi User và Group của SCIM 2.0 (RFC 7643). Các thuộc tính người dùng được hỗ trợ là userName, name.givenName, name.familyName, displayName, emails, active, externalId và preferredLanguage / locale.
Phần mở rộng enterprise user không được triển khai, nên department, manager, employeeNumber, costCenter, division và organization được chấp nhận rồi bỏ qua chứ không được lưu, với cả create, replace lẫn PATCH. Cả Entra và Okta đều ánh xạ sẵn một số thuộc tính này, nên bạn không cần gỡ chúng khỏi bản ánh xạ thuộc tính của mình. Để quy một người dùng về một khách hàng của bạn, hãy đặt tổ chức trên thông tin xác thực SCIM: thuộc tính enterprise organization do nhà cung cấp danh tính của khách hàng khẳng định, và nó cố ý không trở thành org_id của họ.
Scope OAuth
Scope cho phép client yêu cầu các phần cụ thể của dữ liệu hoặc quyền của người dùng. Authagonal hỗ trợ cả scope OIDC chuẩn và scope tùy chỉnh bạn định nghĩa cho API của mình.
Scope tích hợp sẵn
| Scope | Mô tả |
|---|---|
openid | Bắt buộc cho mọi luồng OpenID Connect. Phát hành ID token. |
profile | Trả về các claim hồ sơ chuẩn (name, given_name, family_name, locale, org_name). |
email | Trả về địa chỉ email của người dùng và trạng thái xác minh. |
phone | Trả về số điện thoại của người dùng (phone_number). |
offline_access | Phát hành refresh token cùng với access token. |
roles | Phát claim roles của người dùng. Không có scope này, vai trò sẽ không được phát. |
groups | Phát claim groups của người dùng (tư cách thành viên nhóm SCIM). Không có scope này, nhóm sẽ không được phát. |
Scope tùy chỉnh
Định nghĩa scope của riêng bạn trên trang Scope. Mỗi scope mô tả một quyền hoặc tài nguyên mà client có thể yêu cầu (ví dụ: billing.read, orders.write).


| Trường | Mô tả |
|---|---|
name | Định danh scope được gửi trong yêu cầu token (ví dụ: billing.read). |
displayName | Nhãn dễ đọc hiển thị trên màn hình chấp thuận. |
description | Giải thích dài hơn hiển thị bên dưới tên khi chấp thuận. |
userClaims | Các claim bổ sung được thêm vào access token và ID token khi scope này được cấp. |
showInDiscoveryDocument | Nếu bật, scope sẽ xuất hiện trong /.well-known/openid-configuration. |
emphasize | Làm nổi bật scope như một scope nhạy cảm trên màn hình chấp thuận. |
required | Ngăn người dùng bỏ chọn scope khi chấp thuận. |
group | Nhóm chấp thuận: các scope có chung một tiêu đề xuất hiện cùng nhau trên màn hình chấp thuận dưới một ô đánh dấu. Chỉ để trình bày. |
allowedRoles | Các vai trò mà người dùng phải có để được cấp scope này. Để trống thì cho phép mọi người; người dùng không có vai trò nào trong số này sẽ bị loại scope khỏi token thay vì bị từ chối. |
Tích hợp chấp thuận
Claim tùy chỉnh trên token
Claim tùy chỉnh có hai phần. Nguồn là dữ liệu theo người dùng: mỗi AuthUser có một từ điển customAttributes mà bạn có thể nạp từ Portal (Users → người dùng → Custom Attributes), qua SCIM, hoặc qua hook provisioning TCC. Việc giải phóng theo từng scope: danh sách userClaims của mỗi scope nêu các khóa được phép rời máy chủ.
Khi một client yêu cầu các scope, Authagonal duyệt qua các scope đã cấp, hợp các danh sách userClaims của chúng và chỉ phát ra những khóa đó từ customAttributes của người dùng. Khóa không xác định bị âm thầm bỏ qua — một client không thể đọc một thuộc tính bằng cách đoán tên. Các claim OIDC chuẩn (sub, email, name, v.v.) tuân theo đặc tả và không chịu sự ràng buộc của whitelist.
# 1. On the user (Portal → Users → {user} → Custom Attributes)
department = "engineering"
employee_id = "E-1042"
seat_tier = "enterprise"
# 2. On a custom scope (Portal → Scopes → projects.read)
name = "projects.read"
userClaims = ["department", "seat_tier"] # <-- whitelist
# 3. Client requests scope=openid projects.read
# Decoded access token (relevant fields only):
{
"sub": "u-9b…",
"scope": "openid projects.read",
"department": "engineering",
"seat_tier": "enterprise"
// employee_id is NOT emitted; it's not in the whitelist for any granted scope.
}Claim từ liên kết IdP lấp chỗ trống theo phiên
department được ánh xạ từ assertion SAML, đi qua cùng whitelist scope nhưng chỉ lấp chỗ trống: khi va chạm khóa, giá trị customAttributes đã lưu sẽ thắng. Chúng được phát trên token của phiên này (và sống sót qua các vòng xoay refresh) mà không được ghi ngược về bản ghi người dùng.Gán scope cho client
Thêm scope được phép trên tab Client → Scope & Grant. Client chỉ có thể yêu cầu những scope đã được cấp; scope không xác định sẽ bị từ chối với invalid_scope.
Giao diện
Tùy chỉnh giao diện trang đăng nhập của tenant. Cài đặt giao diện cho phép bạn phù hợp trải nghiệm xác thực với bản sắc thương hiệu sản phẩm — từ logo và màu sắc đến ghi đè CSS nâng cao.
Giao diện
| Cài đặt | Mô tả |
|---|---|
appName | Tên ứng dụng hiển thị trên tiêu đề trang đăng nhập (khi chưa đặt logo) và trong e-mail giao dịch |
logoUrl | URL đến hình ảnh logo. Hiển thị ở đầu trang đăng nhập. Kích thước khuyến nghị: 200x60px hoặc tỷ lệ tương tự. |
primaryColor | Màu thương hiệu chính được sử dụng cho nút, liên kết và trạng thái focus. Đặt qua bộ chọn màu hoặc nhập mã hex. Xem trước trực tiếp cập nhật khi bạn thay đổi giá trị. |
customCssUrl | URL đến file CSS được tải sau kiểu mặc định. File phải được phục vụ từ cùng origin với trang đăng nhập; URL thuộc bất kỳ origin nào khác sẽ bị bỏ qua. |


Cài đặt giao diện với xem trước màu trực tiếp
Thông tin liên hệ
| Cài đặt | Mô tả |
|---|---|
supportEmail | Địa chỉ email hỗ trợ hiển thị trên trang đăng nhập. Người dùng thấy điều này khi cần trợ giúp về tài khoản. |
Bật/tắt trang đăng nhập
Kiểm soát các thành phần hiển thị trên trang đăng nhập tenant:
| Bật/Tắt | Mô tả | Mặc định |
|---|---|---|
showForgotPassword | Hiển thị liên kết "Quên mật khẩu?" trên biểu mẫu đăng nhập | Bật |
showRegistration | Hiển thị liên kết "Đăng ký" cho đăng ký người dùng tự phục vụ | Bật |
poweredBy | Hiển thị huy hiệu "Powered by Authagonal" ở cuối trang đăng nhập | Bật |


Ví dụ trang đăng nhập với giao diện tùy chỉnh
CSS tuỳ chỉnh
Để kiểm soát hoàn toàn giao diện trang đăng nhập, hãy cung cấp URL tệp CSS trong cài đặt thương hiệu. Tệp được tải sau các style mặc định nên luật của bạn có ưu tiên cao hơn. URL phải nằm trên cùng origin với trang đăng nhập; stylesheet từ các origin khác sẽ không được tải.
Thuộc tính CSS tuỳ chỉnh
| Biến | Mô tả | Mặc định |
|---|---|---|
--auth-bg | Màu nền trang | #f3f4f6 |
--auth-card-bg | Nền thẻ đăng nhập | white |
--auth-heading | Màu chữ tiêu đề | #111827 |
--auth-radius | Bán kính bo góc thẻ | 0.5rem |
--auth-font | Họ phông | inherit |
Chế độ tối
Ứng dụng đăng nhập đi kèm với giao diện sáng, tối và theo hệ thống. Cài đặt Chế độ tối trên trang Thương hiệu chọn mặc định: Tắt, Tự động (theo tùy chọn của hệ thống, là mặc định) hoặc Buộc tối. Người dùng vẫn có thể chọn từ công tắc trên trang đăng nhập; lựa chọn được giữ giữa các phiên. Khi ở chế độ system, SPA theo dõi prefers-color-scheme theo thời gian thực.
Giá trị sáng được khai báo tại :root; các ghi đè tối chỉ nằm trong .dark. Branding của tenant qua customCssUrl luôn thắng — màu sắc của bạn được giữ nguyên bất kể chủ đề người dùng.
Bộ chọn phần tử
data-auth. Các bộ chọn này ổn định qua các bản cập nhật — chúng sẽ không bị hỏng khi chúng tôi thay đổi tên lớp nội bộ.| Bộ chọn | Phần tử |
|---|---|
[data-auth="page"] | Khung nền toàn trang |
[data-auth="header"] | Khu vực logo và tên ứng dụng |
[data-auth="logo"] | Hình ảnh logo |
[data-auth="app-name"] | Tiêu đề tên ứng dụng (khi không có logo) |
[data-auth="content"] | Khu vực nội dung chính (biểu mẫu, thông báo) |
[data-auth="login-form"] | Phần tử biểu mẫu đăng nhập |
[data-auth="email-field"] | Bao ngoài ô nhập e-mail |
[data-auth="password-field"] | Bao ngoài ô nhập mật khẩu |
[data-auth="submit-button"] | Nút đăng nhập |
[data-auth="languages"] | Thanh chọn ngôn ngữ |
Cài đặt
Cấu hình chính sách bảo mật toàn tenant, webhook và cài đặt môi trường. Các cài đặt này áp dụng toàn cục cho tất cả client trừ khi bị ghi đè ở cấp client.
Chính sách mật khẩu
Xác định yêu cầu độ phức tạp mật khẩu cho tất cả người dùng trong tenant, tại Người dùng → Cài đặt:
| Cài đặt | Phạm vi | Mặc định |
|---|---|---|
minPasswordLength | 6 – 128 | 8 |
requireUppercase | Bật / Tắt | Bật |
requireLowercase | Bật / Tắt | Bật |
requireDigit | Bật / Tắt | Bật |
requireSpecialChar | Bật / Tắt | Bật |


Cấu hình chính sách mật khẩu
Chính sách MFA
Chính sách MFA toàn tenant, được đặt tại Người dùng → Cài đặt, xác định hành vi xác thực đa yếu tố mặc định. Các client riêng lẻ có thể ghi đè cài đặt này.
| Chính sách | Hành vi |
|---|---|
Disabled | MFA không khả dụng. Người dùng không thể đăng ký MFA. |
Enabled | MFA là tùy chọn. Người dùng có thể chọn đăng ký và sẽ được yêu cầu khi đăng nhập nếu đã đăng ký. |
Required | MFA là bắt buộc. Tất cả người dùng phải đăng ký MFA và hoàn thành yếu tố thứ hai mỗi lần đăng nhập. |
Phiên & Khóa tài khoản
Kiểm soát thời lượng phiên và hành vi khóa tài khoản:
| Cài đặt | Phạm vi | Mặc định |
|---|---|---|
sessionLifetimeMinutes | 5 – 43.200 (30 ngày) | 60 |
maxFailedAttempts | 1 – 100 | 5 |
lockoutDurationMinutes | 1 – 1.440 (24 giờ) | 10 |


Cấu hình phiên và khóa tài khoản
Webhook
Webhook cho phép phản ứng với các sự kiện xác thực theo thời gian thực. Hai sự kiện (onUserAuthenticated, onTokenIssued) có thể bắt buộc — mặc định chúng kích hoạt bất đồng bộ và không chặn người dùng, nhưng bạn có thể bật bắt buộc cho từng sự kiện để phản hồi không phải 2xx hoặc body {"allow": false} sẽ từ chối hành động. Các sự kiện còn lại là thông báo — luôn fire-and-forget, không bao giờ chặn.
| Sự kiện | Loại | Mô tả |
|---|---|---|
onUserAuthenticated | Có thể bắt buộc | Kích hoạt sau khi đăng nhập thành công. Mặc định fire-and-forget nên độ trễ đăng nhập không bị ảnh hưởng. Bật <code>webhookEnforceUserAuthenticated</code> để biến nó thành chặn — phản hồi không phải 2xx hoặc body <code>{"allow": false}</code> sẽ từ chối đăng nhập. |
onTokenIssued | Có thể bắt buộc | Kích hoạt trước khi cấp token (authorization_code, refresh_token, client_credentials). Mặc định fire-and-forget. Bật <code>webhookEnforceTokenIssued</code> để biến nó thành chặn — phản hồi không phải 2xx hoặc body <code>{"allow": false}</code> sẽ ngăn việc cấp token. |
onUserCreated | Thông báo | Thông báo gửi và quên khi người dùng mới đăng ký hoặc được cung cấp qua SCIM. |
onUserUpdated | Thông báo | Thông báo fire-and-forget khi một bản ghi người dùng được cập nhật (thay đổi hồ sơ, vai trò, cập nhật SCIM). |
onUserDeleted | Thông báo | Thông báo fire-and-forget khi một người dùng bị xóa, qua Portal/SCIM hoặc qua chính sách lưu trữ. |
onLoginFailed | Thông báo | Thông báo gửi và quên khi đăng nhập thất bại do thông tin đăng nhập sai, khóa tài khoản hoặc từ chối bởi chính sách. |
Cài đặt webhook bổ sung:
| Cài đặt | Phạm vi | Mặc định | Mô tả |
|---|---|---|---|
webhookTimeoutSeconds | 1 – 30 | 5 | Thời gian chờ tối đa cho phản hồi webhook bắt buộc trước khi hết thời gian |
webhookFailOpen | Bật / Tắt | Bật | Khi bật, nếu webhook bắt buộc không thể truy cập hoặc hết thời gian, thao tác được phép tiếp tục |


Cấu hình sự kiện webhook
Tính khả dụng webhook bắt buộc
webhookFailOpen bị tắt, không người dùng nào có thể đăng nhập. Sử dụng chế độ fail-open trừ khi bạn có yêu cầu tuân thủ nghiêm ngặt buộc phải chặn khi webhook thất bại.Xác minh webhook
Khi bất kỳ URL webhook nào được cấu hình, Authagonal tạo ra một khóa bí mật ký riêng cho từng tenant (một giá trị whsec_… hiển thị chỉ đọc tại Cài đặt → Webhook). Mỗi lần gửi đi đều mang một header X-Authagonal-Signature: t=<unix>,v1=<hex>, trong đó v1 là HMAC-SHA256(secret, "{t}.{body}") được tính trên body thô của yêu cầu. Hãy tính lại nó trên điểm cuối của bạn và so sánh theo thời gian hằng số để xác nhận rằng yêu cầu thực sự đến từ Authagonal và không bị giả mạo — và từ chối các lần gửi có t quá cũ để chặn tấn công phát lại.
import crypto from 'node:crypto';
// rawBody MUST be the exact bytes Authagonal sent: verify before any JSON re-serialization.
function verifyAuthagonalWebhook(signatureHeader, rawBody, signingSecret) {
const parts = Object.fromEntries(signatureHeader.split(',').map((p) => p.split('=')));
const { t, v1 } = parts;
// Replay protection: reject deliveries older than 5 minutes.
if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false;
const expected = crypto
.createHmac('sha256', signingSecret)
.update(`${t}.${rawBody}`)
.digest('hex');
return v1.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(v1), Buffer.from(expected));
}Xoay vòng khóa bí mật ký
Khung giờ bảo trì
Đặt khung giờ bảo trì ưa thích cho các hoạt động gián đoạn như di chuyển dữ liệu của tenant giữa các shard lưu trữ. Chọn giờ UTC (0–23); cổng cũng hiển thị thời gian tương đương theo múi giờ địa phương để thuận tiện.
Đăng ký và truy cập
Ai được phép trở thành người dùng trong tenant của bạn, và họ đăng nhập được với những điều kiện nào.
| Cài đặt | Mặc định | Mô tả |
|---|---|---|
| Đăng ký công khai | Bật | Bất kỳ ai có được phép tự đăng ký hay không. Tắt nó đi sẽ ẩn trang đăng ký và từ chối API đăng ký, và điều đó mới là quan trọng: chỉ ẩn liên kết thôi thì vẫn để ngỏ điểm cuối. Hãy dùng khi bạn tự cung cấp người dùng qua SCIM, qua API hoặc bằng lời mời. |
| Yêu cầu xác minh email để đăng nhập | Bật | Một địa chỉ chưa được xác nhận thì không đăng nhập được. Hãy tắt nếu chính ứng dụng của bạn kiểm soát việc xác minh; dù thế nào claim email_verified vẫn đi kèm token, nên bạn vẫn giữ được tín hiệu đó. |
| Đăng ký client động | Tắt | Cho phép một client tự đăng ký lúc chạy theo RFC 7591, thứ mà một AI agent hoặc một trình kết nối MCP cần có trước khi bắt đầu một luồng. Mặc định tắt, và khi bật thì chỉ mở cửa cho riêng tenant của bạn. Dù thế nào, các lần đăng ký vẫn bị giới hạn tần suất, vẫn bắt buộc PKCE và vẫn bắt buộc có sự đồng ý. |
| Chính sách MFA cho cổng | Vô hiệu hóa | Đa yếu tố cho chính đội ngũ của bạn khi đăng nhập vào cổng, đặt độc lập với chính sách dành cho người dùng cuối. Vô hiệu hóa, đề nghị khi đăng nhập, hoặc bắt buộc. |
| Số người dùng tối đa | Không có | Theo mặc định không có giới hạn tổng số người dùng, và không gói nào đặt giới hạn này. Trong khi địa chỉ email của chủ sở hữu tenant chưa được xác minh, một giới hạn tạm thời 5 người dùng được áp dụng; giới hạn này được gỡ bỏ vĩnh viễn khi địa chỉ được xác minh. |
Lưu giữ người dùng không hoạt động
Tùy chọn vô hiệu hóa rồi xóa những tài khoản đã không còn được dùng, để một thư mục không tích tụ mãi những danh tính ngủ đông. Cả hai đều tắt trừ khi bạn tự đặt, và việc xóa là vĩnh viễn.
| Cài đặt | Mặc định | Mô tả |
|---|---|---|
| Vô hiệu hóa sau (số ngày không hoạt động) | Không bao giờ | Vô hiệu hóa một tài khoản đã không đăng nhập trong khoảng thời gian này. Bản ghi vẫn được giữ và có thể kích hoạt lại. |
| Xóa sau (số ngày không hoạt động) | Không bao giờ | Xóa vĩnh viễn tài khoản. Không có thao tác hoàn tác, nên hãy đặt khoảng cảnh báo và webhook bên dưới trước khi bật tùy chọn này. |
| Số ngày cảnh báo trước | 7 | Webhook cảnh báo kích hoạt trước một lần vô hiệu hóa hoặc xóa bao nhiêu ngày, cho bạn thời gian can thiệp. |
| Webhook lưu giữ | - | Nơi các cảnh báo đó và những hành động đã thực hiện được gửi tới, để bạn có thể báo cho người dùng hoặc giữ tài khoản mở. |
Xuất nhật ký kiểm toán và sao lưu từ xa
Hai cách để lấy dữ liệu của bạn ra theo lịch thay vì theo từng yêu cầu. Xuất nhật ký kiểm toán đẩy mỗi ngày sự kiện kiểm toán đã hoàn tất tới một URL bạn chỉ định, có ký để bạn xác minh được rằng nó đến từ chúng tôi, dùng để nạp vào một SIEM hoặc một kho lưu trữ phục vụ tuân thủ. Sao lưu từ xa gửi bản sao của các bản sao lưu hằng ngày và hằng tuần tới một đích do bạn kiểm soát, không xác thực, xác thực basic hoặc dùng bearer token. Xuất nhật ký kiểm toán được cấu hình trên tab Xuất của trang Nhật ký kiểm tra, còn sao lưu từ xa trên trang Sao lưu; cả hai đều thuộc về bạn để tự giữ, độc lập với các bản sao lưu mà chúng tôi lưu.
Môi trường Sandbox
Trang Môi trường quản lý các môi trường sandbox: các môi trường được đặt tên, tách biệt, có người dùng, client, khóa ký, đăng ký MFA và grant riêng, mỗi môi trường truy cập được tại một URL riêng. Thương hiệu, gói và thanh toán được dùng chung với live. Hãy dùng chúng để kiểm tra thay đổi cấu hình, tích hợp SSO và điểm cuối webhook mà không ảnh hưởng người dùng thực. Theo mặc định bạn có thể tạo tối đa 5 môi trường, và người dùng sandbox đang hoạt động được tính vào MAU của bạn.
| Hành động | Mô tả |
|---|---|
| Thêm môi trường | Tạo một môi trường mới. Tên gồm 1 đến 20 chữ cái thường và chữ số, và "live" là tên dành riêng. Môi trường bắt đầu trống: không có gì được sao chép từ live. |
| Làm mới | Xóa toàn bộ dữ liệu của môi trường và đặt lại về trạng thái trống. |
| Xóa | Xóa vĩnh viễn môi trường sandbox và tất cả dữ liệu của nó. |
Mỗi môi trường truy cập được tại {name}-{slug}.authagonal.io.


Điều khiển môi trường sandbox
Thanh toán
Quản lý đăng ký và thanh toán qua trang Thanh toán của cổng. Trang này cung cấp tổng quan về gói hiện tại và truy cập cổng thanh toán Stripe để quản lý phương thức thanh toán, hóa đơn và thay đổi gói.
Thông tin đăng ký
Trang thanh toán hiển thị chi tiết đăng ký hiện tại một cách nhanh chóng. Bạn sẽ thấy huy hiệu trạng thái cho biết trạng thái đăng ký — active, trialing, past_due, canceled hoặc unpaid — cùng với tên gói, kỳ thanh toán hiện tại (ngày bắt đầu và kết thúc) và liệu đăng ký có được đặt hủy vào cuối kỳ hiện tại hay không.
Quản lý đăng ký
Nhấp nút Quản lý đăng ký để mở cổng thanh toán Stripe trong cửa sổ mới. Từ đó bạn có thể cập nhật phương thức thanh toán, xem và tải hóa đơn, thay đổi gói hoặc hủy đăng ký.
Nếu chưa có đăng ký, nút Thiết lập thanh toán sẽ hiển thị thay thế, hướng dẫn bạn chọn gói và nhập thông tin thanh toán.


Trang thanh toán hiển thị chi tiết đăng ký hiện tại và cung cấp truy cập Stripe
Bảo mật thanh toán
Tên miền tùy chỉnh
Phục vụ trang xác thực từ tên miền riêng (ví dụ: auth.yourdomain.com) thay vì mặc định {slug}.authagonal.io. Tên miền tùy chỉnh mang lại trải nghiệm xác thực liền mạch, mang thương hiệu cho người dùng.
Thêm tên miền
Nhập hostname bạn muốn sử dụng trong biểu mẫu thêm tên miền (ví dụ: auth.yourdomain.com). Sau khi thêm, tên miền sẽ xuất hiện trong danh sách với trạng thái pending_verification.
Xác minh DNS
Tạo hai bản ghi CNAME mà cổng hiển thị cho tên miền, cả hai đều trỏ đến {slug}.authagonal.io: một bản ghi tại chính hostname, dùng để phục vụ lưu lượng và có thể được proxy, và một bản ghi tại _authagonal-challenge. theo sau là hostname, dùng để chứng minh quyền sở hữu và phải ở chế độ chỉ DNS (không proxy). Khi các bản ghi đã sẵn sàng, nhấp Kiểm tra DNS để xác minh. Các tên miền đang chờ cũng được tự động kiểm tra lại.
auth.yourdomain.com. CNAME acme.authagonal.io. _authagonal-challenge.auth.yourdomain.com. CNAME acme.authagonal.io.
Lan truyền DNS
Chứng chỉ TLS
Khi tên miền đã được xác minh, bạn cần chứng chỉ TLS để người dùng kết nối an toàn qua HTTPS. Authagonal hỗ trợ hai tùy chọn:
Tự động (cert-manager) — Authagonal cung cấp và gia hạn chứng chỉ TLS tự động bằng cert-manager. Đây là tùy chọn được khuyến nghị cho hầu hết người dùng. Không cần cấu hình thêm.
Mang chứng chỉ riêng (BYO) — Tải lên chứng chỉ và khóa riêng ở định dạng PEM. Tùy chọn này hữu ích nếu tổ chức yêu cầu chứng chỉ từ cơ quan chứng nhận cụ thể. Hạn chứng chỉ được theo dõi để bạn có thể gia hạn trước khi hết hạn.
Trạng thái tên miền
Mỗi tên miền hiển thị huy hiệu trạng thái cho biết trạng thái hiện tại: pending_verification (DNS chưa xác nhận), verified (DNS đã xác nhận, TLS đang chờ) hoặc active (hoạt động đầy đủ).


Danh sách tên miền hiển thị mỗi tên miền tùy chỉnh và trạng thái hiện tại


Tải lên chứng chỉ TLS và khóa riêng ở định dạng PEM
Gia hạn chứng chỉ BYO
Tổ chức
Tổ chức là một khách hàng bên trong một tenant. Tenant vẫn là ranh giới cô lập: một tiền tố bảng và một khóa ký, trong đó mỗi host của tenant là một issuer riêng. Tổ chức phân vùng danh tính bên trong tenant, nhờ đó một tenant có thể phục vụ nhiều tổ chức khách hàng mà không cần một tenant cho mỗi khách hàng.
Tổ chức đi cùng tên miền tùy chỉnh (một tên miền có thể được ghim vào một tổ chức) và ứng dụng cung cấp (một ứng dụng cung cấp có thể gắn thẻ tổ chức cho người dùng mới). Xem hướng dẫn Ứng dụng nhiều khách hàng để biết mẫu "một tenant, nhiều khách hàng mang thương hiệu riêng" từ đầu đến cuối mà tính năng này sinh ra để phục vụ.
Mô hình và id
Mỗi tổ chức có một id ổn định, bất biến (dạng org_<32 hex>) được phát ra dưới dạng claim token org_id, và một slug bất biến, duy nhất trong tenant, được phát ra dưới dạng org_slug và được tham số authorize organization chấp nhận. Id và slug dùng chung một không gian tra cứu: một slug trùng với id của tổ chức khác bị từ chối như một xung đột, giống hệt trường hợp slug trùng thông thường.
| Trường | Có thể sửa | Mô tả |
|---|---|---|
id | Không | Claim org_id. Được tạo từ org_ + một GUID. Dấu gạch dưới không hợp lệ trong slug, nên một id mới không bao giờ có thể trùng với một slug. |
slug | Không | Claim org_slug, và là giá trị tham số organization chấp nhận. Bất biến vì relying party cố định giá trị này trong mã. |
name | Có | Claim <code>org_name</code>. Có thể chỉnh sửa tự do. |
metadata | Có | Các cặp khóa/giá trị tự do do tenant kiểm soát. Không bao giờ được phát ra trên token trừ khi tập claim của một scope cho phép rõ ràng. |
brandingJson | Có | Đối tượng JSON được gộp theo từng trường lên giao diện thương hiệu của tenant. Xem Ghi đè giao diện bên dưới. |
domains | Chỉ qua endpoint tên miền | Các tên miền email mà tổ chức đã khai báo, mỗi tên miền kèm bản ghi DNS chứng minh quyền sở hữu. Chỉ thay đổi qua các endpoint tên miền bên dưới, không bao giờ qua thao tác cập nhật. |
Tư cách thành viên
Tư cách thành viên là liên kết nhiều-nhiều giữa người dùng và tổ chức, mỗi cặp (tổ chức, người dùng) một dòng. Một người dùng có thể giữ nhiều tư cách; dòng thành viên, chứ không phải thẻ tổ chức cũ gắn trên từng người dùng, là thứ cho phép đăng nhập với tư cách một tổ chức.
| Trạng thái | Cấp token? |
|---|---|
invited | Đã được mời nhưng chưa chấp nhận. Không cho phép cấp token. |
active | Thành viên hợp lệ. Là trạng thái duy nhất cho phép cấp token. |
suspended | Tư cách thành viên bị thu hồi mà không xóa bản ghi. Không cho phép cấp token. |
Các roles của một tư cách thành viên được lấy từ danh mục vai trò hiện có của tenant và được hợp nhất vào claim roles, nhưng chỉ khi tổ chức được yêu cầu chọn rõ ràng (xem Chọn tổ chức cho token) và chỉ từ một dòng thành viên active. Một vai trò giữ trong tổ chức này không bao giờ đến được token phát hành cho tổ chức khác.
Mời vào một tổ chức
POST /api/v1/users/invite nhận thêm organizationId và organizationRoles (tùy chọn). Một lệnh gọi tạo tài khoản với tư cách thành viên invited và gửi e-mail mời mang giao diện thương hiệu của tổ chức. Liên kết mở trên tên miền tùy chỉnh được ghim của tổ chức nếu có. Khi người được mời chấp nhận, tư cách thành viên chuyển thành active. Việc chỉ định một tổ chức yêu cầu quyền owner hoặc admin.
Cung cấp SCIM vào một tổ chức
Một token SCIM có thể được gắn với một tổ chức (organizationId trên POST /api/v1/scim/tokens, hoặc bộ chọn Tổ chức khi tạo token). Id phải là của một tổ chức thuộc tenant. Mọi người dùng mà token đó tạo ra đều trở thành thành viên active và mang tổ chức dưới dạng org_id. Việc gắn chỉ áp dụng lúc tạo, và nó quyết định tư cách thành viên chứ không phải quyền truy cập: hai token trên cùng một client vẫn thấy người dùng của nhau. Xóa một người dùng, bằng bất kỳ cách nào, sẽ xóa các tư cách thành viên của họ.
Cờ chính sách
enabled (mặc định bật): một tổ chức bị vô hiệu hóa không phát token cho chính nó, được kiểm tra cả lúc authorize và ở mọi lần refresh, nên vô hiệu hóa một tổ chức sẽ dừng các phiên đang hoạt động ở lần xoay vòng kế tiếp thay vì chỉ chặn đăng nhập mới.
requireMembershipForTokens (mặc định bật): quy định người dùng có phải giữ tư cách thành viên active để được cấp token cho tổ chức này hay không. Cờ chỉ có tác dụng với lựa chọn rõ ràng (một yêu cầu nêu tên tổ chức, một lần refresh mang theo tổ chức, một kết nối theo phạm vi tổ chức, hoặc một client bị giới hạn đúng một tổ chức). Tổ chức chỉ được thừa hưởng từ thẻ cũ của chính tài khoản thì không bao giờ bị cờ này chặn.
allowAutoMembership (mặc định tắt) cho phép người dùng tham gia mà không cần lời mời khi địa chỉ e-mail đã xác nhận của họ thuộc một trong các tên miền đã xác minh của tổ chức. Được áp dụng lúc authorize và ở mọi lần refresh. Xem Tên miền e-mail và tư cách thành viên tự động bên dưới.
Tên miền e-mail và tư cách thành viên tự động
Một tổ chức khai báo một tên miền e-mail và chứng minh quyền kiểm soát bằng bản ghi DNS TXT. Khi allowAutoMembership bật, người dùng có địa chỉ e-mail đã xác nhận thuộc tên miền đó sẽ trở thành thành viên ngay lần đầu đăng nhập với tư cách tổ chức.
- Khai báo.
POST /api/v1/organizations/{id}/domainskèm tên miền. Phản hồi là201vớirecordName(_authagonal-org.acme.com) vàrecordValue(authagonal-org-verify=<token>). Token được tạo ngẫu nhiên cho từng lần khai báo. - Công bố bản ghi. Thêm một bản ghi TXT với đúng tên và giá trị đó tại DNS của tên miền.
- Xác minh.
POST /api/v1/organizations/{id}/domains/{domain}/verifytra cứu bản ghi. Nếu khớp, trả về200vớiverified: true. Nếu không khớp, trả về409 verification_failed, không bao giờ là200vớiverified: false, để client đang thăm dò thành công không thể nhầm một lần trượt thành thành công. - Gỡ bỏ.
DELETE /api/v1/organizations/{id}/domains/{domain}trả về204. Các tư cách thành viên hiện có được giữ nguyên; chỉ việc tự động tham gia trong tương lai bị dừng.
POST /api/v1/organizations/org_7fa2c9e1.../domains
Content-Type: application/json
{ "domain": "acme.com" }
201 Created
{
"domain": "acme.com",
"verified": false,
"verifiedAt": null,
"createdAt": "2026-10-03T01:02:03Z",
"recordName": "_authagonal-org.acme.com",
"recordValue": "authagonal-org-verify=Qm9...base64url"
}Các lỗi từ chối: 400 domain_invalid (không phải tên DNS thuần), 409 domain_exists (đã có trên tổ chức này), 409 domain_taken (một tổ chức khác trong tenant đang giữ), 404 organization_not_found và 404 domain_not_found. Một tên miền thuộc về nhiều nhất một tổ chức trong mỗi tenant, và điều này được kiểm tra lại ở thời điểm xác minh.
Quy tắc thành viên tự động
Bộ chọn cho phép một người dùng chưa có tư cách thành viên active khi tất cả các điều sau đều đúng:
- Tổ chức được chọn rõ ràng: một refresh grant mang theo tổ chức, một kết nối theo phạm vi tổ chức, tham số
organization(tên miền được ghim cung cấp tham số này), hoặc một client bị giới hạn đúng một tổ chức. Thẻ cũ của chính tài khoản không bao giờ tự động tham gia. - Tổ chức đang được bật và
allowAutoMembershipbật. - E-mail của người dùng đã được xác nhận, vì ai cũng có thể đăng ký là
[email protected]. - Phần e-mail sau ký tự
@cuối cùng, viết thường, bằng chính xác một trong các tên miền của tổ chức đã được xác minh. Không có đối sánh tên miền con:acme.comđã xác minh không chấp nhận[email protected]. Hãy khai báo và xác minh từng tên miền con riêng.
Những gì được ghi, trước khi cổng kiểm tra tư cách thành viên chạy: chưa có dòng nào thì trở thành tư cách thành viên active mới không có vai trò; dòng invited được nâng lên active và giữ nguyên vai trò; dòng active được để nguyên; dòng suspended không bao giờ được nâng cấp.
Xóa thành viên không ngăn họ quay lại
allowAutoMembership đang bật, một thành viên đã bị xóa nhưng vẫn đủ điều kiện sẽ tham gia lại ở lần authorize hoặc refresh kế tiếp. Để chặn một người dùng đủ điều kiện, hãy đặt tư cách thành viên của họ thành suspended, trạng thái duy nhất mà quy tắc không bao giờ thay đổi.Chọn tổ chức cho token
Một yêu cầu được phân giải về tổ chức nào chỉ được quyết định ở đúng một nơi, nên kết quả giống hệt nhau tại /connect/authorize, ở mọi lần refresh, và trên device grant. Thứ tự ưu tiên, từ cao đến thấp:
| # | Nguồn | Hành vi |
|---|---|---|
| 1 | Grant mang theo (refresh) | Tổ chức mà một token trước đó được phát hành cho. Nếu tổ chức không còn tồn tại, bản thân lần refresh bị từ chối thay vì quay về bất cứ thứ gì khác. |
| 2 | Kết nối theo phạm vi tổ chức | Phiên đăng nhập qua một kết nối SAML hoặc OIDC thuộc về một tổ chức, nên tổ chức đó được chọn. Đây là nguồn duy nhất được chứng minh thay vì chỉ được khẳng định. Một yêu cầu nêu tên tổ chức khác bị từ chối, và một kết nối mà tổ chức của nó không còn tồn tại cũng vậy. |
| 3 | organization | Được phân giải theo slug trước, sau đó theo id. Tên miền được ghim đi vào đúng nhánh này: middleware thêm nó trước khi yêu cầu được đánh giá. Nếu nêu tên mà không tìm thấy thì bị từ chối hẳn, không bao giờ lặng lẽ quay về giá trị khác. |
| 4 | Client bị giới hạn đúng một tổ chức | Tự động chọn: ứng dụng dành riêng cho từng khách hàng đăng ký tổ chức duy nhất của mình một lần và không bao giờ gửi tham số. Bị giới hạn ở <em>nhiều hơn</em> một tổ chức mà không có gợi ý nào thì bị từ chối với <code>account_selection_required</code>. |
| 5 | Thẻ tổ chức cũ của chính tài khoản | Một chuỗi phẳng duy nhất, được phân giải theo id bằng một lần tra cứu, không phải quét các tư cách thành viên của người dùng. Nếu nó không trỏ đến dòng tổ chức thực nào, nó được phát ra nguyên văn mà không bị chặn, đúng như trước khi tổ chức tồn tại. Nó không bao giờ là một lựa chọn rõ ràng, nên không bao giờ tự động tham gia. |
| 6 | Không có nguồn nào ở trên | Token không có tổ chức nào: không có claim <code>org_id</code>, <code>org_slug</code> hay <code>org_name</code>. |
Tư cách thành viên không bao giờ là gợi ý
requireMembershipForTokens được kiểm tra và, nếu áp dụng, việc tự động tham gia được thử.Ghim tên miền
Một tên miền tùy chỉnh có thể được ghim vào một tổ chức, biến tên miền đó thành cửa chính của tổ chức. Việc ghim được middleware phân giải tenant áp dụng cho cả GET /connect/authorize (được thêm vào query string) và POST /connect/par (thay vào đó, phần body được đẩy lên được viết lại, vì PAR đọc tham số từ payload đã lưu). Xem Tên miền tùy chỉnh để biết toàn bộ cơ chế.
PUT /api/v1/custom-domains/auth.acme.com/organization
Content-Type: application/json
{ "organizationId": "org_7fa2c9e1..." }Tên miền được ghim từ chối yêu cầu xung đột
400 access_denied, trước khi bất kỳ trang đăng nhập nào được hiển thị. Nếu không có điều này, một relying party có thể gửi tham số organization của riêng nó và việc ghim chỉ còn là hình thức.Kết nối theo phạm vi tổ chức
Một kết nối SAML hoặc OIDC có thể thuộc về một tổ chức. Đăng nhập qua nó sẽ chọn tổ chức đó và tạo tư cách thành viên active khi người dùng chưa có. Dòng invited được chấp nhận: nó trở thành active và giữ nguyên vai trò cùng người mời, nên người được mời đăng nhập qua IdP của họ không bao giờ cần e-mail. Một thành viên suspended vẫn bị đình chỉ và bị từ chối khi cấp token. Điều này không phụ thuộc vào allowAutoMembership hay tên miền, vì tổ chức đã được chọn sẵn bởi kết nối.
Tên tổ chức trên trang đăng nhập
Trang đăng nhập hiển thị Signing in to {name} bên dưới tên ứng dụng. Tên lấy từ chính tổ chức mà giao diện thương hiệu của trang lấy: tổ chức của tên miền được ghim, rồi tổ chức được nêu trong yêu cầu authorize, rồi tổ chức bị giới hạn duy nhất của client. Dòng này bị ẩn khi không có tổ chức, hoặc khi tên tổ chức bằng tên ứng dụng, để phần đầu trang không bao giờ hiện "Acme / Signing in to Acme".
Ghi đè giao diện
brandingJson của tổ chức được gộp theo từng trường lên giao diện thương hiệu của tenant cho trang đăng nhập: khóa có mặt và không null thì ghi đè, khóa vắng mặt hoặc null thì kế thừa, và khóa không xác định bị bỏ qua. JSON sai định dạng sẽ quay về giao diện của chính tenant kèm một cảnh báo được ghi log, không bao giờ làm trang tải thất bại.
Tab Giao diện chỉnh sửa cả 21 trường có thể gộp: diện mạo (appName, logoUrl, primaryColor, customCssUrl), màu chế độ sáng và tối, màu e-mail, supportEmail, showForgotPassword, poweredBy và languages. Mỗi trường hoặc kế thừa giá trị của tenant, hiển thị dưới dạng gợi ý, hoặc ghi đè nó, với nút Xóa để gỡ khóa.
showRegistration không thể bị ghi đè
Điền bù từ thẻ tổ chức cũ
Trước khi có tổ chức, một người dùng có thể mang một thẻ tổ chức dạng văn bản tự do mà không có bản ghi nào đứng sau. POST /api/v1/organizations/backfill chuyển nó thành các tổ chức và tư cách thành viên thực, nhóm theo từng giá trị cũ riêng biệt. Đây là lần chạy thử trừ khi phần thân là { "dryRun": false }.
- Có giới hạn: quét tối đa 50,000 người dùng mỗi lần gọi. Phản hồi
truncatednghĩa là hãy chạy lại; những người dùng đã chuyển sẽ được bỏ qua ở lần chạy lại. - Idempotent: một giá trị cũ riêng biệt đã được chuyển sẽ được khớp bằng dấu nội bộ, không phải bằng tên hiển thị (có thể sửa) của tổ chức, nên đổi tên tổ chức kết quả sau đó không gây trùng lặp ở lần chạy kế tiếp.
{
"dryRun": true,
"organizationsCreated": 3,
"membershipsCreated": 41,
"usersSkipped": 0,
"organizations": [
{ "legacyValue": "acme-corp", "slug": "acme-corp", "users": 22 }
],
"truncated": false
}Hướng dẫn giao diện cổng
Trang Tổ chức liệt kê mọi tổ chức trong tenant, mỗi lần 50 mục với nút Tải thêm, và có Tổ chức Mới (chỉ slug và tên; cờ chính sách, tên miền và giao diện được đặt sau) cùng luồng Lấp đầy từ trường tổ chức cũ chạy phần điền bù ở trên dưới dạng xem trước, rồi Áp dụng.


Danh sách tổ chức hiển thị mọi tổ chức khách hàng trong tenant cùng slug, tên và ngày tạo
Trang chi tiết của mỗi tổ chức có ba tab: Chung (tên, slug chỉ đọc, ba công tắc chính sách, thẻ Tên miền email để thêm, xác minh và gỡ tên miền e-mail cũng như sao chép bản ghi TXT, và thao tác xóa yêu cầu gõ slug để xác nhận), Branding (mọi trường có thể ghi đè, mỗi trường kế thừa giá trị của tenant hoặc ghi đè nó), và Thành viên (thêm theo e-mail, kèm đề nghị gửi lời mời khi chưa có tài khoản, đổi trạng thái và gỡ theo từng dòng, kèm Tải thêm).


Tab Thành viên liệt kê từng tư cách thành viên cùng trạng thái và điều khiển theo từng dòng để đổi hoặc gỡ


Tab Giao diện ghi đè từng trường giao diện đăng nhập của tenant cho tổ chức này
Trang Tên miền có bộ chọn tên miền → tổ chức: mỗi thẻ tên miền có một danh sách thả xuống ngay trên thẻ, liệt kê các tổ chức của tenant cùng tùy chọn "Tenant (không có)" để bỏ ghim, được áp dụng ngay khi thay đổi. Bộ chọn tương tự cũng xuất hiện khi thêm tên miền.


Bộ chọn tổ chức ngay trên thẻ tên miền ghim tên miền tùy chỉnh đó vào một tổ chức
Sự kiện kiểm toán
organization.created · organization.updated · organization.deleted · organization.member.added · organization.member.invited · organization.member.joined · organization.member.updated · organization.member.removed · organization.domain_added · organization.domain_verified · organization.domain_removed · organization.backfill · domain.organization_set
Phân trang
Danh sách tổ chức và danh sách thành viên được phân trang theo cursor và trả về { items, nextCursor }. Truyền limit (mặc định 50, giới hạn từ 1 đến 200) và, sau trang đầu, truyền nguyên vẹn nextCursor của phản hồi trước làm cursor. nextCursor null là trang cuối. Cursor là một vị trí keyset mờ trên id tổ chức (hoặc id người dùng với thành viên), nên việc thêm hoặc xóa dòng giữa các lần gọi không thể làm lệch hay lặp một trang. Một cursor mà danh sách không phát hành là 400 invalid_cursor.
Quản lý tổ chức từ trợ lý AI
MCP cổng được host cung cấp mười ba công cụ về tổ chức, tất cả yêu cầu vai trò tenant admin: liệt kê, lấy, tạo, cập nhật và xóa tổ chức; liệt kê, thêm, cập nhật và gỡ thành viên; thêm, xác minh và gỡ tên miền e-mail; và liệt kê các tổ chức của một người dùng. Chúng gọi cùng các thao tác như API ở trên, nên một công cụ không thể lệch khỏi route của nó. Xem Vận hành cổng của bạn từ trợ lý AI.
Một issuer cho mỗi host
Mỗi host của một tenant là một OIDC issuer riêng. Khi host của yêu cầu được phân giải qua bảng tên miền của tenant, issuer và mọi URL endpoint mà discovery công bố là https://{host}, nên mỗi tên miền tùy chỉnh đang hoạt động tự khẳng định iss của mình và host tenant chuẩn không thay đổi. Khóa ký là theo tenant, nên mọi host đều phục vụ cùng một tập khóa. Đây là điều cho phép một tenant đứng trước nhiều khách hàng, mỗi khách hàng trên tên miền mang thương hiệu riêng được ghim vào tổ chức của họ. Xem Tên miền tùy chỉnh.
Cấu hình e-mail
Cấu hình cách tenant gửi e-mail giao dịch, chẳng hạn e-mail xác minh, đặt lại mật khẩu và lời mời. Chọn giữa người gửi chia sẻ mặc định, tên miền tuỳ chỉnh đã xác minh qua Resend, hoặc máy chủ SMTP của riêng bạn.


E-mail bản địa hoá
E-mail giao dịch được gửi bằng ngôn ngữ ưu tiên của người nhận. Các e-mail xác minh, đặt lại mật khẩu, tài khoản đã tồn tại, chào mừng, lời mời, xóa tài khoản, hỗ trợ và thanh toán đều có mẫu trong mười một ngôn ngữ: tiếng Anh, tiếng Đức, tiếng Pháp, tiếng Tây Ban Nha, tiếng Bồ Đào Nha, tiếng Việt, tiếng Trung giản thể, tiếng Nhật, tiếng Ả Rập, tiếng Hindi và tiếng Afrikaans. Khi không có mẫu cho ngôn ngữ của người nhận, e-mail sẽ mặc định về tiếng Anh.
Ngôn ngữ được xác định từ tuỳ chọn đã lưu của người nhận tại thời điểm gửi. Tuỳ chọn này có thể đến từ nhiều nơi:
- Đăng ký và tạo tài khoản — lấy từ ngôn ngữ người dùng đã chọn trên các màn hình đăng nhập được lưu trữ.
- Trang Người dùng trong portal — do quản trị viên đặt khi tạo hoặc chỉnh sửa người dùng.
- Cung cấp qua SCIM: ánh xạ từ
preferredLanguage(hoặclocale) của IdP khi người dùng được đồng bộ qua SCIM. - Trang tài khoản tự phục vụ — do chính người dùng chọn tại
/login/account.
Không cần cấu hình
Nhà cung cấp e-mail
| Nhà cung cấp | Mô tả | Cài đặt |
|---|---|---|
| Authagonal (Default) | E-mail gửi từ [email protected] qua hạ tầng Resend dùng chung của chúng tôi. | Không cần cấu hình — dùng được ngay. |
| Custom Domain (Resend) | E-mail gửi từ tên miền đã xác minh của bạn qua Resend. | Đăng ký tên miền, thêm bản ghi DNS, xác minh quyền sở hữu. |
| Custom SMTP | E-mail gửi qua máy chủ SMTP của riêng bạn. | Cung cấp máy chủ SMTP, cổng, thông tin đăng nhập và cấu hình TLS. |
Danh tính người gửi
E-mail và tên người gửi được dùng chung cho mọi chế độ nhà cung cấp. E-mail người gửi là bắt buộc đối với nhà cung cấp Tên miền tùy chỉnh (Resend) và SMTP tùy chỉnh; nếu tên người gửi trống, sẽ lùi về tên ứng dụng trong phần thương hiệu.
| Trường | Mô tả |
|---|---|
emailSenderEmail | Địa chỉ From của e-mail gửi đi. Phải thuộc tên miền đã xác minh khi dùng chế độ Tên miền tùy chỉnh (Resend). |
emailSenderName | Tên hiển thị trong hộp thư của người nhận. |
Tên miền tuỳ chỉnh Resend
Xác minh tên miền gửi với Resend một lần, sau đó dùng làm địa chỉ From cho tenant. Các bản ghi DNS (SPF, DKIM) được hiển thị trong bảng Tên miền gửi tùy chỉnh tại Cài đặt → Email; Resend kiểm tra chúng khi bạn nhấp <strong>Xác minh</strong>.
SMTP tuỳ chỉnh
Mang máy chủ SMTP của riêng bạn — hữu ích cho relay nội bộ, nhà cung cấp không nằm trong Resend hoặc ghim theo quy định.
| Trường | Mô tả |
|---|---|
smtpHost | Tên máy chủ SMTP (ví dụ smtp.example.com). |
smtpPort | Cổng kết nối, mặc định 587. TLS được thương lượng bằng STARTTLS; không hỗ trợ TLS ngầm trên cổng 465. Dùng 25 cho relay nội bộ không xác thực. |
smtpUsername | Tên đăng nhập xác thực (tuỳ chọn — để trống nếu không xác thực). |
smtpPassword | Mật khẩu xác thực. Được lưu mã hoá trong secret cài đặt tenant. |
smtpUseTls | Bắt buộc TLS. Để bật trừ khi bạn dùng relay nội bộ tin cậy. |
Tên miền gửi tuỳ chỉnh
Khi dùng nhà cung cấp Tên miền tùy chỉnh (Resend), bạn có thể đăng ký tên miền riêng để e-mail gửi từ thương hiệu của bạn (ví dụ [email protected]) thay vì @authagonal.io.
- Vào Cài đặt → Email và chọn nhà cung cấp Tên miền tùy chỉnh (Resend).
- Nhập tên miền và nhấn Đăng ký tên miền.
- Thêm các bản ghi DNS được hiển thị (DKIM, SPF và return path) vào DNS của tên miền.
- Nhấn Kiểm tra xác minh — sau khi DNS lan truyền (thường 1–10 phút), trạng thái tên miền sẽ chuyển thành đã xác minh.
Lan truyền DNS
Kiểm thử
Dùng nút Gửi e-mail thử nghiệm trong Cài đặt → E-mail để xác minh cấu hình. Một e-mail thử nghiệm sẽ được gửi tới địa chỉ quản trị của bạn với cài đặt hiện đã lưu.
Nhật ký kiểm toán
Nhật ký kiểm toán cung cấp bản ghi chỉ đọc về tất cả hành động quản trị được thực hiện trên tenant. Mọi thay đổi qua cổng hoặc API đều được ghi lại với đầy đủ ngữ cảnh, cung cấp dấu vết hoàn chỉnh cho tuân thủ và khắc phục sự cố.
Các cột nhật ký
| Cột | Mô tả |
|---|---|
| Thời gian | Ngày và giờ hành động xảy ra |
| Người thực hiện | Địa chỉ email của quản trị viên thực hiện hành động, hoặc "system" cho hành động tự động |
| Hành động | Loại hành động được thực hiện (ví dụ: Client Created, Settings Updated) |
| Thực thể | Mục tiêu của hành động ở định dạng type:id (ví dụ: client:my-app) |
| Chi tiết | Ngữ cảnh bổ sung về thay đổi |
Hành động được theo dõi
Các hành động quản trị sau được ghi trong nhật ký kiểm toán:
| Danh mục | Hành động |
|---|---|
| Ứng dụng | Client Created, Client Updated, Client Deleted |
| Kết nối SSO | SAML Connection Created, SAML Connection Deleted, OIDC Connection Created, OIDC Connection Deleted |
| Người dùng | User Created, User Updated |
| Cài đặt | Settings Updated, Branding Updated |
| Tên miền | Domain Added, Domain Verified, Domain Deleted |
| SCIM | SCIM Token Created, SCIM Token Revoked |
| Vai trò | Role Created, Role Updated, Role Deleted |
| Nhóm | Group Created, Group Deleted |
| Nhóm quản trị | Team Member Invited, Team Member Removed |


Nhật ký kiểm toán cung cấp bản ghi đầy đủ về tất cả hành động quản trị
Lưu giữ
Sao lưu
Authagonal tự động sao lưu dữ liệu tenant của bạn theo lịch hàng giờ. Bản sao lưu bao gồm tất cả người dùng, nhóm, vai trò, client, kết nối SSO, token SCIM, thương hiệu và cài đặt. Bạn có thể xem lịch sử sao lưu và tải xuống bản sao lưu đầy đủ mới nhất từ trang Sao lưu.


Cách sao lưu hoạt động
- Mỗi ngày một lần, các bản sao lưu gia tăng hằng giờ được gộp thành một bản sao lưu đầy đủ mới, và vào Chủ nhật các bản đầy đủ hằng ngày được gộp thành một bản sao lưu hằng tuần. Hệ thống giữ bảy bản sao lưu hằng ngày và bốn bản sao lưu hằng tuần.
- Bản sao lưu tăng dần chạy hàng giờ, chỉ thu thập các hàng thay đổi kể từ lần sao lưu cuối cùng.
- Bản sao lưu được lưu trong Azure Blob Storage với cùng danh tính được quản lý mà tenant của bạn sử dụng.
- Các bản ghi đã xoá được theo dõi qua tombstone và được đưa vào bản sao lưu để đảm bảo tính đầy đủ cho kiểm tra.
Tải xuống bản sao lưu
Nhấn "Tải mới nhất" để lấy tệp ZIP chứa bản sao lưu đầy đủ mới nhất được ghép với tất cả các bản tăng dần sau đó. Mỗi bảng được xuất ra tệp JSONL (mỗi dòng là một đối tượng JSON).
Định dạng sao lưu
Ứng dụng cung cấp
Ứng dụng provisioning là dịch vụ của chính bạn, được Authagonal gọi mỗi khi một người dùng được tạo, để chúng có thể thiết lập tài khoản, gán license, quyết định người dùng thuộc tổ chức nào, hoặc từ chối hẳn việc đăng ký.
Cách hoạt động
Khi một người dùng được tạo, Authagonal gọi URL callback của ứng dụng provisioning của bạn theo mẫu TCC (Try/Confirm/Cancel). Mọi ứng dụng đều phải chấp nhận ở pha Try trước khi bất kỳ ứng dụng nào được commit, nhờ đó nhiều hệ thống phía sau có thể cùng đồng ý, hoặc một hệ thống có thể phủ quyết, mà không để lại những tài khoản tạo dở dang.
| Giai đoạn | Điểm cuối | Mục đích |
|---|---|---|
| /try | POST {callbackUrl}/try | Kiểm tra xem ứng dụng có thể xử lý người dùng không. Trả về 200 để chấp nhận hoặc 4xx để từ chối. |
| /confirm | POST {callbackUrl}/confirm | Xác nhận thao tác sau khi tất cả ứng dụng đã chấp nhận giai đoạn /try. |
| /cancel | POST {callbackUrl}/cancel | Hoàn tác thao tác nếu ứng dụng khác thất bại trong giai đoạn /try. |
Khi nào provisioning chạy
Provisioning chạy trên mọi luồng tạo người dùng, không chỉ khi người dùng tự đăng ký. Các cặp ứng dụng và người dùng đã được provision sẽ bị bỏ qua, nên mỗi ứng dụng chỉ thấy mỗi người dùng một lần.
| Luồng tạo người dùng | Khi nào kích hoạt |
|---|---|
POST /api/auth/register | Người dùng tự đăng ký |
| Callback SAML ACS | Lần đăng nhập SSO đầu tiên của người dùng mới (JIT) |
| Callback OIDC | Lần đăng nhập SSO đầu tiên của người dùng mới (JIT) |
POST /scim/v2/Users | Một connector provision người dùng từ thư mục của khách hàng |
| Tạo người dùng trong portal và admin | Người vận hành tạo hoặc mời người dùng thủ công |
Yêu cầu Try
Authagonal POST JSON này tới <code>{callbackUrl}/try</code>. Các trường không có giá trị sẽ bị bỏ qua thay vì được gửi là null.
| Trường | Loại | Mô tả |
|---|---|---|
transactionId | string | Định danh giao dịch provisioning này. Cùng giá trị đó được gửi tới /confirm và /cancel, nên hãy chuẩn bị sẵn công việc của bạn theo giá trị này, rồi commit hoặc hủy bỏ khi lời gọi đó đến. |
userId | string | Id Authagonal của người dùng. Đây là subject bạn sẽ thấy trong token của họ. |
email | string | Địa chỉ email của người dùng. |
firstName | string | Tên, khi luồng tạo có cung cấp. |
lastName | string | Họ, khi luồng tạo có cung cấp. |
organizationId | string | Tổ chức mà người dùng đã thuộc về, nếu có. Chỉ xuất hiện khi trước đó đã có thứ gì đó gán tổ chức; ở lần đăng ký đầu tiên trường này vắng mặt, và đó là dấu hiệu để bạn gán tổ chức. |
customAttributes | object | Các thuộc tính tùy chỉnh đã lưu của người dùng. Với người dùng được tạo qua SSO, phần này bao gồm federated_connection, tên của kết nối đã bảo chứng cho họ. |
Người dùng đến qua SSO là trường hợp phổ biến đáng để tính trước: họ chưa có tổ chức, và federated_connection cho bạn biết họ đến từ khách hàng nào của bạn.
{
"transactionId": "8f14e45fceea167a5a36dedd4bea2543",
"userId": "0f6b1c8e-3d2a-4f51-9e77-2c1a4b5d6e7f",
"email": "[email protected]",
"firstName": "Ada",
"lastName": "Lovelace",
"customAttributes": {
"federated_connection": "acme-okta"
}
}Phản hồi Try
Ứng dụng của bạn trả về 200 kèm một body JSON. Body này không chỉ là lời xác nhận đã nhận: đó là cách một ứng dụng phía sau gán tổ chức và các thuộc tính rồi cuối cùng xuất hiện trên token của người dùng.
| Trường | Loại | Mô tả |
|---|---|---|
approved | boolean | Ứng dụng này có chấp nhận người dùng hay không. Mặc định là true nếu bỏ trống. False sẽ từ chối việc đăng ký và tài khoản mới bị xóa. |
reason | string | Lý do người dùng bị từ chối. Được hiển thị cho bên đã gọi luồng tạo. |
organizationId | string | Tổ chức mà người dùng này thuộc về. Được lưu trên người dùng và phát ra dưới dạng claim org_id trên token của họ. Chỉ được áp dụng nếu người dùng chưa có tổ chức, nên ứng dụng trả lời đầu tiên sẽ thắng và các ứng dụng sau nhìn thấy phép gán đó. |
customAttributes | object | Các thuộc tính cần merge vào người dùng, theo từng khóa. Được phát ra trên token thông qua cấu hình UserClaims của một scope. |
emailVerified | boolean | Ứng dụng của bạn bảo đảm rằng nó đã xác minh địa chỉ này, ví dụ bằng cách đổi một lời mời đã gửi tới đó. Authagonal đánh dấu tài khoản là đã xác nhận và bỏ qua email xác minh của chính nó. |
{
"approved": true,
"organizationId": "org_acme",
"customAttributes": { "org_role": "member" }
}Đây là nơi org_id sinh ra
org_id khi yêu cầu không nêu tổ chức nào, chính là giá trị mà ứng dụng provisioning của bạn đã trả về ở organizationId. Khi đó là id của một tổ chức trong tenant, token mang org_id, org_slug và org_name của tổ chức đó, và một tổ chức bị vô hiệu sẽ từ chối việc đăng nhập. Mọi giá trị khác được phát ra nguyên văn dưới dạng org_id, không có quy tắc duy nhất và không có yêu cầu về định dạng. Việc trả về một id tổ chức không tạo ra tư cách thành viên. Bạn cũng có thể đặt trực tiếp bằng PUT /api/v1/users/{userId}, và lọc theo nó bằng GET /api/v1/users?organizationId=.Gắn người dùng với đúng tổ chức
Hãy quyết định tổ chức ở đây, tại một chỗ duy nhất, thay vì ở từng luồng tạo. Người dùng SSO mang theo federated_connection, thứ xác định kết nối đã xác thực họ và do đó xác định khách hàng, và vẫn đúng khi một khách hàng liên kết nhiều miền email. Người dùng được mời thì không có kết nối, nên hãy đối chiếu họ theo lời mời mà bạn đã phát hành. Cả hai luồng đều đi tới /try trước khi người dùng tồn tại, nên một đoạn logic duy nhất bao trọn cả hai và không có hai quy tắc để lệch nhau.
// POST {callbackUrl}/try
app.post('/provisioning/try', async (req, res) => {
const { email, customAttributes } = req.body;
// An SSO user carries the connection that vouched for them. That is the
// customer, and it stays right when one customer has several domains.
const connection = customAttributes?.federated_connection;
const org = connection
? await orgByConnection(connection)
: await orgByPendingInvite(email);
if (!org) return res.json({ approved: false, reason: 'No organization for this user' });
// Stamped on the user and emitted as org_id on every token from now on.
res.json({ approved: true, organizationId: org.id });
});Từ chối sẽ xóa tài khoản
approved: false, người dùng vừa được tạo sẽ bị xóa để không còn tài khoản provision dở dang nào sót lại. Các luồng tạo qua API trả về 422 kèm reason của bạn; callback SAML và OIDC trả về 400. Hãy trả về approved: true cho người dùng mà bạn không cần làm gì.Thêm ứng dụng cung cấp
Để thêm ứng dụng cung cấp, cung cấp Tên ứng dụng, Callback URL, API Key tùy chọn và Timeout của Try tùy chọn (tính bằng giây, mặc định 60, phạm vi 5 đến 300; Confirm và Cancel dùng một timeout ngắn cố định). Khóa API được gửi dưới dạng Bearer token trong header Authorization của mỗi yêu cầu webhook, cho phép ứng dụng xác thực yêu cầu từ Authagonal.
Kiểm tra
Nhấp Kiểm tra bên cạnh bất kỳ ứng dụng cung cấp nào để gửi yêu cầu thử đến URL callback. Kết quả kiểm tra hiển thị mã trạng thái HTTP và nội dung phản hồi, giúp bạn xác minh ứng dụng nhận và xử lý webhook chính xác.


Kiểm tra ứng dụng cung cấp để xác minh gửi và xử lý webhook
Giới hạn gói
Số lượng ứng dụng cung cấp tối đa có thể cấu hình cho mỗi tenant, với giới hạn mặc định là 6. Giới hạn này có thể được điều chỉnh bởi quản trị viên nếu quy trình của bạn cần thêm mục tiêu cung cấp.
Xác thực bằng khóa API
Nhóm quản trị
Trang Nhóm quản trị quản lý các quản trị viên cổng: những người có thể truy cập và cấu hình tenant qua cổng quản lý. Mỗi thành viên có một vai trò (Owner, Admin, Developer hoặc Support) quyết định những gì họ có thể thay đổi.
Danh sách quản trị viên
Danh sách quản trị viên hiển thị tên, địa chỉ email, vai trò và ngày thêm của mỗi thành viên. Chỉ báo "Bạn" được hiển thị bên cạnh hàng của người dùng hiện tại để bạn dễ dàng nhận ra tài khoản của mình.
Mời quản trị viên
Để mời thành viên mới, cung cấp địa chỉ email, tên và vai trò của họ. Họ sẽ nhận được email kèm liên kết để đặt mật khẩu và kích hoạt tài khoản; liên kết có hiệu lực trong 7 ngày.
Trường mời
Lời mời quản trị viên tạo một tài khoản đang chờ và gửi email chứa liên kết kích hoạt cho người được mời.
| Trường | Mô tả |
|---|---|
email | Địa chỉ email của quản trị viên mới. Phải duy nhất trong tenant. |
name | Tên hiển thị trong danh sách quản trị viên. |
role | Vai trò được cấp: tenant:admin, tenant:developer hoặc tenant:support. Mặc định là tenant:admin. Không thể cấp vai trò owner qua lời mời. |
Xóa quản trị viên
Chủ sở hữu tenant có thể nhấp Xóa bỏ bên cạnh bất kỳ thành viên nào để thu hồi quyền truy cập. Hộp thoại xác nhận được hiển thị trước khi hoàn tất xóa. Bạn không thể tự xóa mình, và tenant luôn giữ lại chủ sở hữu của nó.


Quản lý quản trị viên cổng từ trang Nhóm quản trị
Quyền sở hữu
Hỗ trợ
Mở một yêu cầu hỗ trợ với đội ngũ Authagonal mà không cần rời khỏi portal. Mỗi yêu cầu là một cuộc trò chuyện theo luồng, nên bạn và đội ngũ của chúng tôi luôn nắm chung thông tin từ lúc báo cáo đầu tiên đến khi giải quyết xong.
Các yêu cầu của bạn
Trang hỗ trợ liệt kê mọi yêu cầu bạn đã tạo, hoạt động mới nhất lên đầu. Dùng huy hiệu trạng thái để biết ngay yêu cầu nào đang chờ bạn và yêu cầu nào đang chờ chúng tôi.


Các yêu cầu hỗ trợ của bạn với tiêu đề, trạng thái, mức ưu tiên và hoạt động gần nhất
- Mỗi hàng hiển thị tiêu đề, trạng thái hiện tại (đang mở, đang chờ, đã giải quyết hoặc đã đóng), mức ưu tiên và thời điểm của hoạt động gần nhất.
- Nhấn Yêu cầu mới để mở một yêu cầu, sau đó đặt tiêu đề, mức ưu tiên và tin nhắn đầu tiên của bạn.
- Huy hiệu trạng thái được mã hóa màu giúp dễ dàng quét qua danh sách để tìm những yêu cầu cần bạn chú ý.
Một luồng yêu cầu
Mở một yêu cầu sẽ hiển thị toàn bộ cuộc trò chuyện. Các phản hồi đăng theo thứ tự, và tin nhắn mới từ đội ngũ của chúng tôi xuất hiện mà không cần tải lại trang.


Một luồng yêu cầu giữa bạn và đội ngũ Authagonal
- Tin nhắn theo luồng giữa bạn và đội ngũ Authagonal được hiển thị theo thứ tự thời gian.
- Trả lời ngay tại chỗ và đính kèm tệp để chia sẻ log, ảnh chụp màn hình hoặc cấu hình.
- Luồng cập nhật trực tiếp, nên phản hồi từ đội ngũ của chúng tôi hiển thị ngay khi vừa được gửi.
- Nếu bạn trả lời email thông báo thay vào đó, tin nhắn của bạn được tự động ghép vào luồng.
Cách phản hồi đến với bạn
Bộ phận hỗ trợ cho người dùng của bạn
Tách biệt với phần hỗ trợ mà bạn nhận từ chúng tôi, Authagonal có thể vận hành một bộ phận hỗ trợ cho người dùng cuối của bạn. Họ gửi yêu cầu từ các trang tài khoản trên máy chủ mang thương hiệu riêng của tenant bạn, và đội ngũ của bạn trả lời từ cổng.
Nó tồn tại vì những người không đăng nhập được cũng chính là những người không thể với tới một công cụ hỗ trợ đòi hỏi phải đăng nhập. Bộ phận hỗ trợ nằm ngay cạnh các màn hình đăng nhập, nên một người dùng bị khóa ngoài vẫn còn lối vào, và mọi yêu cầu đều đến nơi với sẵn liên kết tới một tài khoản có thật trong thư mục của bạn, thay vì tới bất kỳ địa chỉ nào đó mà ai đấy gõ vào.
Bật tính năng
Mở Hỗ trợ khách hàng trong cổng, chuyển sang tab Cài đặt của nó và bật Bật hỗ trợ khách hàng. Tab này dành cho owner và admin. Người dùng của bạn không thấy gì cho tới khi bạn làm điều đó.
| Cài đặt | Mô tả |
|---|---|
| Bật hỗ trợ khách hàng | Công tắc tổng. Khi tắt, cả các trang dành cho người dùng cuối lẫn hộp thư của người vận hành đều bị ẩn và API của chúng trả về 404. |
| Cho phép yêu cầu từ khách chưa đăng nhập | Cho phép một khách chưa đăng nhập gửi yêu cầu, tức là trường hợp bị khóa ngoài. Được bảo vệ bằng một bước kiểm tra bot, và cuộc trao đổi tiếp diễn qua email kèm một liên kết riêng tư, vì không có tài khoản nào để đăng nhập. |
| Thông báo qua email | Ai được nhận email khi có yêu cầu mới hoặc khi một người dùng trả lời: không ai cả, các địa chỉ cụ thể, hoặc toàn bộ đội hỗ trợ của bạn (owner, admin và support), để không ai phải ngồi canh hộp thư. |
| Ngôn ngữ khách hàng mặc định | Ngôn ngữ được giả định cho một người dùng khi chúng tôi chưa biết ngôn ngữ của họ, dùng cho các yêu cầu và email của họ. Ngôn ngữ đã lưu của chính người dùng luôn được ưu tiên, và nếu không đặt gì thì là tiếng Anh. Cài đặt này nằm trên tab <strong>Chung</strong> của Cài đặt. |
| URL webhook hỗ trợ | Một URL để POST các sự kiện của yêu cầu tới, nhằm đẩy chúng vào công cụ của riêng bạn. |
Không có trên gói Free
Người dùng của bạn nhìn thấy gì
Người dùng đã đăng nhập có một khu vực hỗ trợ trong các trang tài khoản trên máy chủ tenant của bạn, mang thương hiệu của bạn. Họ có thể gửi một yêu cầu, xem lại mọi yêu cầu đã gửi và trả lời trong một luồng. Phản hồi từ đội ngũ của bạn cũng đến qua email, nên người dùng không phải liên tục vào kiểm tra.
Khi yêu cầu ẩn danh được bật, một người không đăng nhập được vẫn có thể gửi yêu cầu. Họ cung cấp một địa chỉ email và nội dung của mình, rồi nhận về một liên kết riêng tư dẫn tới cuộc trò chuyện. Liên kết đó là lối vào duy nhất, nên hãy coi nó như một thông tin xác thực: nó không thể đoán được, và bất kỳ ai giữ nó đều có thể đọc và trả lời đúng luồng đó.
Hộp thư của người vận hành
Đội ngũ của bạn trả lời từ Hỗ trợ khách hàng trong menu bên của cổng. Đây là nơi tách biệt với các yêu cầu của chính bạn gửi cho chúng tôi, và nó dành cho vai trò tenant:support trở lên, nên bạn có thể cho một nhân viên hỗ trợ dùng bộ phận hỗ trợ mà không phải trao cho họ phần còn lại của cổng.
| Hành động | Mô tả |
|---|---|
| Trả lời | Đăng vào luồng. Người dùng được gửi email và thấy nội dung ngay lập tức nếu đang mở trang. |
| Phân công | Giao một yêu cầu cho một thành viên cụ thể trong đội của bạn, để hai người không cùng trả lời một yêu cầu. |
| Trạng thái và mức ưu tiên | Chuyển một yêu cầu qua các trạng thái đang mở, đang chờ, đã giải quyết và đã đóng, và đánh dấu mức độ khẩn cấp của nó. Yêu cầu đã đóng bị xóa sau một thời gian lưu giữ, thay vì được giữ mãi mãi. |
| Ghi chú nội bộ | Ghi chú chỉ đội ngũ của bạn nhìn thấy, người dùng thì không bao giờ. Việc chỉnh sửa và xóa đều được ghi lại trong nhật ký kiểm toán. |
| Mở thay mặt một người dùng | Bắt đầu một luồng với một trong những người dùng của bạn bằng cách chọn họ từ thư mục, dành cho khi cuộc trò chuyện đã bắt đầu ở nơi khác. |
| Chuyển lên Authagonal | Nếu hóa ra một yêu cầu là về Authagonal chứ không phải sản phẩm của bạn, hãy chuyển nó lên. Thao tác đó mở một yêu cầu liên kết với đội ngũ của chúng tôi, có thể kèm theo luồng trò chuyện tới thời điểm đó, và nối hai yêu cầu lại để bạn theo dõi được cả hai. Mỗi yêu cầu chỉ có thể chuyển lên một lần. |
Người dùng viết bằng ngôn ngữ của họ
Một yêu cầu được lưu bằng chính ngôn ngữ mà người dùng đã viết, và mỗi người trong luồng đọc nó bằng ngôn ngữ của mình. Nhân viên hỗ trợ của bạn thấy tin nhắn đã dịch sang ngôn ngữ cổng của họ, người dùng thấy phản hồi của bạn đã dịch sang ngôn ngữ của họ, và văn bản gốc luôn được giữ kèm bên cạnh. Ngôn ngữ được nhận diện từ tin nhắn đầu tiên và gắn cố định vào yêu cầu. Bản dịch được tính một lần cho mỗi ngôn ngữ rồi dùng lại, nên một luồng dài không tự dịch lại từ đầu.
Múi giờ
Mỗi yêu cầu ghi lại múi giờ mà người dùng đã gửi nó đi. Sau đó mỗi tin nhắn hiển thị giờ địa phương của họ bên cạnh giờ của bạn, nên một phản hồi lúc 14:32 hiện đúng là 02:32 như nó thực sự đã diễn ra với người đang chờ. Không có gì được hiển thị khi múi giờ không xác định, chẳng hạn một yêu cầu đến qua email, hoặc khi nó trùng với múi giờ của bạn.
Webhook
Đặt một URL webhook hỗ trợ để nhận các sự kiện của yêu cầu ngay khi chúng xảy ra, dùng để phát cảnh báo hoặc phản chiếu yêu cầu sang hệ thống của riêng bạn. Payload được ký nên bạn có thể xác minh chúng đến từ chúng tôi.
| Sự kiện | Mô tả |
|---|---|
support.ticket.created | Một người dùng đã gửi một yêu cầu. |
support.ticket.message | Một tin nhắn đã được đăng vào một luồng, bởi một người dùng hoặc bởi một người vận hành của bạn. Trường fromStaff trong payload cho bạn biết là ai. |
support.ticket.status_changed | Trạng thái của một yêu cầu đã thay đổi, ví dụ thành đã giải quyết. |
support.ticket.assigned | Một yêu cầu đã được giao cho một thành viên trong đội. |
Nhập & di chuyển
Di chuyển một hệ thống định danh hiện có vào tenant Authagonal của bạn. Hỗ trợ hai nguồn — Duende IdentityServer (một cơ sở dữ liệu SQL Server) và Auth0 (Management API). Mỗi nguồn chạy một bản xem trước chỉ đọc để bạn xem chính xác những gì sẽ được sao chép trước khi xác nhận.
Nhập từ Duende IdentityServer
Chuyển clients, scopes, người dùng và vai trò từ một cơ sở dữ liệu SQL Server Duende IdentityServer hiện có sang tenant Authagonal của bạn. Quá trình nhập chạy theo hai giai đoạn — xem trước và commit — để bạn xem xét những gì sẽ được sao chép trước khi có bất kỳ thay đổi nào.
Những gì được nhập
Trình nhập đọc ConfigurationDb của Duende và các bảng ASP.NET Identity rồi ghi các hàng đã ánh xạ vào tenant của bạn. Các thành phần ngắn hạn như persisted grants, device codes và khóa ký được bỏ qua.
| Đối tượng | Bảng nguồn | Ghi chú |
|---|---|---|
| Clients | Clients, ClientSecrets, ClientGrantTypes, ClientScopes, ClientRedirectUris | Clients bị tắt sẽ được nhập ở trạng thái tắt. Secrets đã hết hạn bị bỏ qua. |
| Scopes | ApiScopes, ApiResources, IdentityResources | Các ánh xạ claim người dùng được giữ nguyên khi nhận diện được. |
| Người dùng | AspNetUsers, AspNetUserClaims | Hash mật khẩu (ASP.NET Identity V3) được sao chép nguyên vẹn và re-hash ở lần đăng nhập đầu tiên. |
| Vai trò | AspNetRoles, AspNetUserRoles | Các gán vai trò được giữ nguyên. |
| Đăng nhập bên ngoài | AspNetUserLogins | Lưu để tham chiếu; kết nối lại IdP thượng nguồn qua SSO sau khi nhập. |
Xem trước trước khi commit
Dán chuỗi kết nối ConfigurationDb / IdentityDb Duende của bạn và nhấn Xem trước. Xem trước mở kết nối chỉ đọc và đếm từng hàng sẽ được nhập. Không ghi gì cả.
- Số lượng đối tượng cho clients, scopes, người dùng, vai trò và phân công vai trò.
- Cảnh báo xung đột khi tenant đích đã có clients (các ClientId trùng khớp sẽ bị ghi đè), vai trò hoặc scopes (các tên trùng khớp sẽ bị bỏ qua).
- Cảnh báo về bảng không xác định và cột không được ánh xạ để bạn biết dữ liệu nào sẽ bị bỏ.


Bảng xem trước với số liệu và cảnh báo
Hash mật khẩu
Duende lưu mật khẩu bằng ASP.NET Identity V3 (PBKDF2). PasswordHasher của Authagonal xác minh trực tiếp định dạng đó và re-hash sang định dạng bản địa ở lần đăng nhập thành công đầu tiên — người dùng giữ nguyên mật khẩu cũ mà không cần quy trình đặt lại.
Đối chiếu User ID
Nếu một người dùng đã có trong tenant này có cùng email với một bản ghi sắp nhập, quá trình nhập sẽ xoay userId của tài khoản đó sang sub nguồn trước khi nhập, để các vai trò, đăng nhập và claims được nhập gắn vào tài khoản hiện có và các ứng dụng vốn đã tham chiếu người dùng qua sub nguồn của họ vẫn phân giải được sau khi chuyển đổi. Mật khẩu và hồ sơ hiện có của tài khoản được giữ nguyên; các vai trò nguồn được hợp nhất lên trên. Bản xem trước liệt kê mọi tài khoản sẽ được đối chiếu trước khi bạn commit.
Chạy quá trình nhập
Nhấn Bắt đầu nhập sau khi xem lại bản xem trước. Giai đoạn commit ghi clients, scopes, người dùng, vai trò và tham chiếu đăng nhập bên ngoài vào các store của tenant. Các client có clientId trùng khớp sẽ bị ghi đè; các hàng có scope name, email hoặc role name trùng khớp sẽ bị bỏ qua, nên có thể chạy lại trình nhập an toàn.
Những gì không được nhập
- Persisted grants, device codes, session máy chủ — ngắn hạn, được tạo lại tự động.
- Khóa ký — Authagonal phát hành khóa riêng cho mỗi tenant.
- Cột và bảng tùy chỉnh — mọi thứ ngoài schema chuẩn của Duende sẽ hiện dưới dạng cảnh báo để bạn biết dữ liệu đó đã bị bỏ.
- Clients bị tắt — được nhập ở trạng thái tắt; bật lại từ trang Clients khi cần.
Không có trong sandbox
Nhập từ Auth0
Kết nối Authagonal với Management API của tenant Auth0 và mang theo các ứng dụng, API, vai trò, người dùng và kết nối doanh nghiệp của bạn. ID người dùng và ứng dụng được nhập sẽ được giữ nguyên, nên các tham chiếu sub và client_id hiện có vẫn phân giải được sau khi chuyển đổi.
Những gì bạn cần
Tạo một ứng dụng Machine-to-Machine trong Auth0 được ủy quyền cho Management API, với các scope đọc sau: read:users, read:clients, read:resource_servers, read:roles, read:connections, read:client_grants. Dán domain, client ID và client secret của nó vào biểu mẫu nhập — chúng chỉ được dùng cho việc nhập.
Những gì được nhập
| Đối tượng | Bảng nguồn | Ghi chú |
|---|---|---|
| Ứng dụng | clients, client-grants | Public và confidential được phát hiện tự động. Client secrets được re-hash để tiếp tục hoạt động. |
| API & scopes | resource-servers | Audiences và scopes được gán cho từng client từ các grant của nó. |
| Vai trò | roles + phân quyền | Phân quyền vai trò theo từng người dùng được giữ nguyên. |
| Người dùng | users + identities | Hồ sơ và metadata được chuyển sang; danh tính mạng xã hội/doanh nghiệp trở thành các đăng nhập được liên kết. |
| Kết nối | connections (OIDC) | Các kết nối OIDC doanh nghiệp trở thành nhà cung cấp liên kết. Các kết nối SAML, mạng xã hội và cơ sở dữ liệu bị bỏ qua kèm cảnh báo. |
Mật khẩu
Management API của Auth0 không bao giờ trả về hash mật khẩu. Nếu bạn có bản xuất mật khẩu hàng loạt được bộ phận hỗ trợ của Auth0 trợ giúp (NDJSON), hãy cung cấp nó — các hash bcrypt được nhập nguyên vẹn và người dùng giữ nguyên mật khẩu mà không cần đặt lại. Tệp đó cũng chứa toàn bộ tập người dùng của bạn, gỡ bỏ giới hạn liệt kê 1.000 người dùng của API Auth0. Không có nó, người dùng được nhập dưới dạng hồ sơ và đặt mật khẩu mới ở lần đăng nhập đầu tiên.
Cùng bản xem trước, xoay vòng và giới hạn
Tham chiếu API
Mỗi tenant cung cấp một máy chủ OIDC tuân thủ tiêu chuẩn tại https://{slug}.authagonal.io. Tất cả điểm cuối tuân theo đặc tả OAuth 2.0 và OpenID Connect. Tham chiếu này bao gồm mọi điểm cuối mà ứng dụng của bạn có thể cần tương tác.
Luồng Authorization Code với PKCE
OIDC Discovery & JWKS
Tài liệu discovery cho phép thư viện OIDC client tự động cấu hình. Không cần xác thực cho cả hai điểm cuối.
GET /.well-known/openid-configuration
Trả về tài liệu cấu hình OpenID Provider. Phản hồi bao gồm tất cả metadata mà client cần để tương tác với tenant này.
| Trường | Mô tả |
|---|---|
| issuer | URL issuer của tenant |
| authorization_endpoint | URL cho yêu cầu ủy quyền |
| token_endpoint | URL cho trao đổi token |
| userinfo_endpoint | URL để lấy claims người dùng |
| jwks_uri | URL cho JSON Web Key Set |
| revocation_endpoint | URL cho thu hồi token |
| introspection_endpoint | URL cho introspection token |
| end_session_endpoint | URL cho đăng xuất / kết thúc phiên |
| device_authorization_endpoint | URL cho yêu cầu ủy quyền thiết bị |
| pushed_authorization_request_endpoint | URL của endpoint Pushed Authorization Request (RFC 9126). |
| require_pushed_authorization_requests | Liệu tenant có yêu cầu PAR ở mức toàn cục hay không. Ngay cả khi giá trị này là false, từng client riêng lẻ vẫn có thể đặt RequirePushedAuthorizationRequests = true. |
| scopes_supported | Danh sách các phạm vi được hỗ trợ |
| response_types_supported | Các loại phản hồi được hỗ trợ |
| grant_types_supported | Các loại cấp quyền được hỗ trợ |
| code_challenge_methods_supported | Phương thức PKCE được hỗ trợ (S256) |
| backchannel_logout_supported | Hỗ trợ đăng xuất back-channel hay không |
GET /.well-known/openid-configuration/jwks
Trả về JSON Web Key Set dùng để xác minh chữ ký token. Phản hồi chứa mảng keys gồm các khóa công khai EC P-256 (token được ký bằng ES256), mỗi khóa bao gồm các trường kty (EC), use, kid, alg, crv, x và y.
curl https://acme.authagonal.io/.well-known/openid-configuration
Điểm cuối Authorization
GET /connect/authorize
Khởi tạo luồng mã ủy quyền. Người dùng phải có phiên đang hoạt động hoặc sẽ được chuyển hướng đến trang đăng nhập. Khi thành công, người dùng được chuyển hướng trở lại ứng dụng với mã ủy quyền.
| Tham số | Bắt buộc | Mô tả |
|---|---|---|
response_type | Có | Phải là "code" |
client_id | Có | Mã định danh client đã đăng ký của bạn |
redirect_uri | Có | Phải khớp chính xác với URI chuyển hướng đã đăng ký |
scope | Có | Danh sách phạm vi cách nhau bởi dấu cách (ví dụ: "openid profile email") |
state | Khuyến nghị | Giá trị mờ để bảo vệ CSRF, được trả về không thay đổi trong chuyển hướng |
code_challenge | Bắt buộc nếu dùng PKCE | Mã băm SHA-256 được mã hóa base64url của code_verifier |
code_challenge_method | Bắt buộc nếu dùng PKCE | Phải là "S256" |
nonce | Tùy chọn | Giá trị gắn với ID token để bảo vệ chống phát lại |
login_hint | Tùy chọn | Điền sẵn trường email trên trang đăng nhập |
Phản hồi thành công: Chuyển hướng 302 đến redirect_uri với tham số truy vấn code và state.
Phản hồi lỗi: Chuyển hướng 302 với tham số truy vấn error, error_description và state.
Yêu cầu PKCE
code_verifier (chuỗi ngẫu nhiên từ 43 ký tự trở lên), băm bằng SHA-256, và mã hóa base64url kết quả để tạo code_challenge.Pushed Authorization Requests (PAR)
RFC 9126. Thay vì đặt mọi tham số authorize trên URL, client của bạn POST chúng tới /connect/par với xác thực client thông thường và nhận lại một request_uri mờ đục, có thời gian sống ngắn. Trình duyệt sau đó truy cập /connect/authorize?client_id=...&request_uri=... — không có thông tin nào khác lọt vào lịch sử trình duyệt, log máy chủ hay header Referer, và máy chủ đã xác minh tính toàn vẹn của tham số dưới quyền xác thực client.
POST /connect/par
Xác thực client giống với /connect/token: HTTP Basic với client_id/client_secret, hoặc thông tin đăng nhập mã hóa trong form. Public client gửi không cần secret. Body chứa các tham số bạn vẫn gửi tới /connect/authorize; bản thân request_uri bị từ chối (nối chuỗi PAR bị cấm theo §2.1 của đặc tả). Trả về 201 Created.
| Tham số | Bắt buộc | Mô tả |
|---|---|---|
client_id | Có | Client ID của bạn. Phải khớp với client đã xác thực. |
client_secret | Client bí mật | Client secret của bạn. Bắt buộc với confidential client. |
response_type | Có | Phải là "code" |
redirect_uri | Có | Phải khớp chính xác với URI chuyển hướng đã đăng ký |
scope | Có | Danh sách phạm vi cách nhau bởi dấu cách (ví dụ: "openid profile email") |
code_challenge | Bắt buộc nếu dùng PKCE | Mã băm SHA-256 được mã hóa base64url của code_verifier |
code_challenge_method | Bắt buộc nếu dùng PKCE | Phải là "S256" |
state | Khuyến nghị | Giá trị mờ để bảo vệ CSRF, được trả về không thay đổi trong chuyển hướng |
nonce | Tùy chọn | Giá trị gắn với ID token để bảo vệ chống phát lại |
Phản hồi
| Trường | Mô tả |
|---|---|
request_uri | Tham chiếu mờ đục dùng một lần, ví dụ <code>urn:ietf:params:oauth:request_uri:abc123…</code>. Truyền nó cho <code>/connect/authorize</code> dưới dạng <code>request_uri</code>. |
expires_in | Thời gian sống của <code>request_uri</code> tính bằng giây. Mặc định là 90 — giá trị điển hình của IdP tham chiếu. |
Ở lệnh tiếp theo GET /connect/authorize?client_id=…&request_uri=…, mọi tham số khác được lấy từ payload đã đẩy và mọi tham số query thừa bị bỏ qua. client_id ở lệnh authorize phải khớp với client đã đẩy yêu cầu. Sau khi được tiêu thụ (hoặc khi expires_in hết hạn), request_uri bị xóa khỏi kho lưu trữ.
Bắt buộc PAR theo từng client
/connect/authorize thông thường từ nó. Tư thế khuyến nghị cho client rủi ro cao là kết hợp RequirePushedAuthorizationRequests = true với PKCE, điều này loại bỏ hoàn toàn thanh URL như một bề mặt tấn công.# 1. Push parameters (server returns request_uri + expires_in) curl -X POST https://acme.authagonal.io/connect/par \ -u "my-app:CLIENT_SECRET" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "response_type=code" \ -d "redirect_uri=https://app.example.com/callback" \ -d "scope=openid profile email" \ -d "state=$(openssl rand -hex 16)" \ -d "code_challenge=YOUR_CODE_CHALLENGE" \ -d "code_challenge_method=S256" # 2. Send the user to /authorize with only client_id + request_uri # https://acme.authagonal.io/connect/authorize?client_id=my-app&request_uri=urn:ietf:params:oauth:request_uri:abc123...
Điểm cuối Token
POST /connect/token
Trao đổi thông tin xác thực lấy token. Yêu cầu phải sử dụng Content-Type: application/x-www-form-urlencoded. Xác thực client có thể thông qua HTTP Basic auth (Authorization: Basic base64(client_id:client_secret)) hoặc dưới dạng tham số trong phần thân biểu mẫu (client_id + client_secret).
Cấp quyền Authorization Code
| Tham số | Bắt buộc | Mô tả |
|---|---|---|
grant_type | Có | "authorization_code" |
code | Có | Mã ủy quyền từ chuyển hướng |
redirect_uri | Có | Phải khớp với URI sử dụng trong yêu cầu ủy quyền |
code_verifier | Bắt buộc nếu dùng PKCE | Chuỗi ngẫu nhiên gốc dùng để tạo code_challenge |
client_id | Có | Mã định danh client (nếu không dùng Basic auth) |
client_secret | Client bí mật | Client secret (nếu không dùng Basic auth) |
Cấp quyền Refresh Token
| Tham số | Bắt buộc | Mô tả |
|---|---|---|
grant_type | Có | "refresh_token" |
refresh_token | Có | Refresh token để trao đổi |
client_id | Có | Mã định danh client của bạn |
client_secret | Client bí mật | Client secret của bạn |
Cấp quyền Client Credentials
| Tham số | Bắt buộc | Mô tả |
|---|---|---|
grant_type | Có | "client_credentials" |
client_id | Có | Mã định danh client của bạn |
client_secret | Có | Client secret của bạn |
scope | Tùy chọn | Phạm vi cách nhau bởi dấu cách để yêu cầu |
Cấp quyền Device Code
| Tham số | Bắt buộc | Mô tả |
|---|---|---|
grant_type | Có | "urn:ietf:params:oauth:grant-type:device_code" |
device_code | Có | Device code từ phản hồi ủy quyền thiết bị |
client_id | Có | Mã định danh client của bạn |
client_secret | Client bí mật | Client secret của bạn |
Phản hồi token:
| Trường | Mô tả |
|---|---|
access_token | Access token cho các lệnh gọi API |
token_type | "Bearer" |
expires_in | Thời hạn token tính bằng giây |
id_token | OpenID Connect ID token (khi phạm vi openid được yêu cầu) |
refresh_token | Refresh token (khi phạm vi offline_access được cấp) |
curl -X POST https://acme.authagonal.io/connect/token \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=authorization_code" \ -d "code=AUTHORIZATION_CODE" \ -d "redirect_uri=https://app.example.com/callback" \ -d "client_id=my-app" \ -d "code_verifier=YOUR_CODE_VERIFIER"
Điểm cuối UserInfo
GET /connect/userinfo
Trả về claims về người dùng đã xác thực. Yêu cầu access token hợp lệ với phạm vi openid.
| Trường | Loại | Mô tả |
|---|---|---|
sub | string | Mã định danh người dùng duy nhất |
email | string | Địa chỉ email người dùng |
email_verified | boolean | Email đã được xác minh hay chưa |
given_name | string | Tên |
family_name | string | Họ |
name | string | Tên hiển thị đầy đủ |
phone_number | string | Số điện thoại (nếu có). Được phát theo scope <code>phone</code>. |
org_id | string | Tổ chức mà người dùng thuộc về. Được gán bởi ứng dụng provisioning của chính bạn (xem Ứng dụng provisioning) hoặc đặt bằng PUT /api/v1/users/{userId}; Authagonal không bao giờ tự suy ra nó. Được phát hành theo scope profile, và vắng mặt khi người dùng không có tổ chức nào. |
roles | string[] | Mảng các vai trò được gán. Chỉ được phát khi token mang scope <code>roles</code>. |
groups | object[] | Mảng thành viên nhóm, mỗi phần tử có id và name. Chỉ được phát khi token mang scope <code>groups</code>. |
curl https://acme.authagonal.io/connect/userinfo \ -H "Authorization: Bearer ACCESS_TOKEN"
Token Introspection (RFC 7662)
POST /connect/introspect
Xác thực token và trả về metadata. Yêu cầu thông tin xác thực client (Basic auth hoặc tham số phần thân biểu mẫu).
| Tham số | Bắt buộc | Mô tả |
|---|---|---|
token | Có | Token cần introspect |
token_type_hint | Tùy chọn | Gợi ý về loại token (ví dụ: "refresh_token") |
Phản hồi token đang hoạt động:
| Trường | Mô tả |
|---|---|
active | true |
sub | Chủ thể (ID người dùng) |
client_id | Client mà token được cấp cho |
scope | Phạm vi được cấp cách nhau bởi dấu cách |
iss | Issuer |
exp | Thời gian hết hạn (Unix timestamp) |
iat | Thời gian cấp (Unix timestamp) |
aud | Audience |
token_type | Loại token (ví dụ: "Bearer") |
Phản hồi token không hoạt động: { "active": false }
Luôn trả về 200 OK
active: false. Ngoại lệ duy nhất là chính bên gọi: client xác thực thất bại sẽ nhận 401 invalid_client.curl -X POST https://acme.authagonal.io/connect/introspect \ -u "my-app:CLIENT_SECRET" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "token=ACCESS_OR_REFRESH_TOKEN"
Thu hồi Token (RFC 7009)
POST /connect/revocation
Thu hồi token đã cấp trước đó. Yêu cầu thông tin xác thực client.
| Tham số | Bắt buộc | Mô tả |
|---|---|---|
token | Có | Token cần thu hồi |
token_type_hint | Tùy chọn | Gợi ý về loại token (ví dụ: "refresh_token") |
Điểm cuối luôn trả về 200 OK, ngay cả với token không hợp lệ hoặc đã bị thu hồi, theo đặc tả RFC 7009.
Access token và refresh token
Ủy quyền Thiết bị (RFC 8628)
POST /connect/deviceauthorization
Khởi tạo luồng ủy quyền thiết bị cho các thiết bị hạn chế đầu vào (CLI, smart TV, thiết bị IoT). Thiết bị hiển thị mã cho người dùng, người dùng sau đó phê duyệt yêu cầu trên thiết bị khác có trình duyệt.
| Tham số | Bắt buộc | Mô tả |
|---|---|---|
client_id | Có | Mã định danh client của bạn |
client_secret | Client bí mật | Client secret của bạn |
scope | Tùy chọn | Phạm vi cách nhau bởi dấu cách (mặc định là "openid") |
Phản hồi:
| Trường | Mô tả |
|---|---|
device_code | Mã xác minh thiết bị (dùng để polling) |
user_code | Mã hiển thị cho người dùng ở định dạng XXXX-XXXX |
verification_uri | URL người dùng truy cập để nhập mã |
verification_uri_complete | URL với user_code đã điền sẵn |
expires_in | Mặc định là 300 (giây, nên mã có hiệu lực trong 5 phút). Đặt theo từng client. |
interval | 5 (giây — khoảng thời gian polling tối thiểu) |
Luồng phê duyệt: Người dùng truy cập verification_uri, nhập user_code và phê duyệt yêu cầu. Trong khi đó, thiết bị polling điểm cuối token với device_code.
Mã lỗi polling:
| Lỗi | Ý nghĩa |
|---|---|
authorization_pending | Người dùng chưa phê duyệt — tiếp tục polling |
expired_token | Device code đã hết hạn — bắt đầu lại luồng |
access_denied | Người dùng từ chối yêu cầu ủy quyền |
curl -X POST https://acme.authagonal.io/connect/deviceauthorization \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "client_id=my-cli" \ -d "scope=openid profile email"
Kết thúc Phiên / Đăng xuất
GET POST /connect/endsession
Đăng xuất phiên người dùng hiện tại, thông báo cho mọi client có URI đăng xuất back-channel hoặc front-channel đã đăng ký, và thu hồi các grant gắn với phiên đó. Nếu không có id_token_hint khớp với phiên hiện tại, người dùng sẽ được yêu cầu xác nhận việc đăng xuất trước.
| Tham số | Bắt buộc | Mô tả |
|---|---|---|
id_token_hint | Tùy chọn | ID token — dùng để xác thực post_logout_redirect_uri |
post_logout_redirect_uri | Tùy chọn | Nơi chuyển hướng sau khi đăng xuất (phải được đăng ký) |
state | Tùy chọn | Giá trị mờ được trả về trong chuyển hướng |
Nếu post_logout_redirect_uri hợp lệ được cung cấp và khớp với URI đã đăng ký, người dùng nhận chuyển hướng 302. Ngược lại, phản hồi JSON xác nhận phiên đã kết thúc.
Đăng xuất Back-Channel
BackChannelLogoutUri của mỗi client. JWT chứa sub, aud, iss và claim sự kiện http://schemas.openid.net/event/backchannel-logout. Ứng dụng của bạn nên vô hiệu hóa phiên cục bộ của người dùng khi nhận được thông báo này.Tham chiếu SCIM 2.0 API
Authagonal hỗ trợ giao thức SCIM 2.0 cho cung cấp người dùng và nhóm tự động. Các nhà cung cấp danh tính như Okta, Azure AD và OneLogin có thể sử dụng API này để giữ tenant Authagonal đồng bộ với thư mục doanh nghiệp.
URL cơ sở: https://{slug}.authagonal.io/scim/v2
Xác thực: Tất cả yêu cầu cần Bearer token. Tạo token SCIM trong cổng trên trang SCIM: chọn client mà IdP của bạn cung cấp người dùng cho nó, sau đó nhấp Tạo Token.
Header chung:
| Header | Giá trị |
|---|---|
Authorization | Bearer SCIM_TOKEN |
Content-Type | application/scim+json |
Các điểm cuối danh sách nhận count (mặc định 100, tối đa 200; 0 chỉ trả về tổng số) và lọc qua tham số filter (ví dụ: userName eq "[email protected]"). Người dùng được phân trang bằng cursor: truyền nextCursor của phản hồi trước. Nhóm chấp nhận startIndex (bắt đầu từ 1) hoặc cursor.
Người dùng
GET /scim/v2/Users: Liệt kê người dùng với phân trang và lọc tùy chọn.
| Tham số truy vấn | Mô tả |
|---|---|
startIndex | Với Users chỉ chấp nhận giá trị 1; hãy phân trang bằng cursor thay thế. Giá trị lớn hơn trả về 400 invalidValue. |
cursor | Con trỏ phân trang không trong suốt (opaque): truyền nextCursor của trang trước để lấy trang tiếp theo |
count | Số kết quả tối đa mỗi trang (mặc định: 100, tối đa: 200; 0 chỉ trả về tổng số) |
filter | Biểu thức lọc SCIM (ví dụ: userName eq "[email protected]") |
GET /scim/v2/Users/{id}: Lấy một người dùng theo ID người dùng Authagonal.
POST /scim/v2/Users: Tạo người dùng mới. Trả về 201 Created.
| Trường | Bắt buộc | Mô tả |
|---|---|---|
userName | Có | Địa chỉ email (phải là duy nhất trong tenant) |
name.givenName | Không | Tên |
name.familyName | Không | Họ |
displayName | Không | Tên hiển thị đầy đủ |
active | Không | Người dùng có đang hoạt động hay không (mặc định: true) |
externalId | Không | Mã định danh từ nhà cung cấp danh tính upstream |
PUT /scim/v2/Users/{id}: Thay thế toàn bộ tài nguyên người dùng. Tất cả trường phải được cung cấp.
PATCH /scim/v2/Users/{id}: Cập nhật một phần bằng SCIM PatchOp.
| Thao tác | Đường dẫn được hỗ trợ | Giá trị mẫu |
|---|---|---|
replace | userName, active, name.givenName, name.familyName, displayName, externalId, preferredLanguage | true / false, hoặc giá trị chuỗi |
add | userName, active, name.givenName, name.familyName, displayName, externalId, preferredLanguage | true / false, hoặc giá trị chuỗi |
remove | name.givenName, name.familyName, displayName, externalId, preferredLanguage | (không cần giá trị) |
DELETE /scim/v2/Users/{id}: Xóa mềm người dùng (vô hiệu hóa tài khoản và thu hồi tất cả token). Trả về 204 No Content.
curl -X POST https://acme.authagonal.io/scim/v2/Users \
-H "Authorization: Bearer SCIM_TOKEN" \
-H "Content-Type: application/scim+json" \
-d '{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"userName": "[email protected]",
"name": {
"givenName": "Jane",
"familyName": "Smith"
},
"displayName": "Jane Smith",
"active": true,
"externalId": "ext-12345"
}'Nhóm
GET /scim/v2/Groups: Liệt kê tất cả nhóm với phân trang và lọc tùy chọn.
GET /scim/v2/Groups/{id}: Lấy một nhóm theo ID, bao gồm danh sách thành viên.
POST /scim/v2/Groups: Tạo nhóm mới. Trả về 201 Created.
| Trường | Bắt buộc | Mô tả |
|---|---|---|
displayName | Có | Tên hiển thị nhóm |
members | Không | Mảng đối tượng thành viên, mỗi đối tượng có trường value chứa ID người dùng |
externalId | Không | Mã định danh từ nhà cung cấp danh tính upstream |
PUT /scim/v2/Groups/{id}: Thay thế toàn bộ tài nguyên nhóm (bao gồm danh sách thành viên).
PATCH /scim/v2/Groups/{id}: Cập nhật một phần: thêm, xóa hoặc thay thế thành viên, hoặc thay đổi displayName và externalId.
DELETE /scim/v2/Groups/{id}: Xóa cứng nhóm. Trả về 204 No Content.
curl -X PATCH https://acme.authagonal.io/scim/v2/Groups/GROUP_ID \
-H "Authorization: Bearer SCIM_TOKEN" \
-H "Content-Type: application/scim+json" \
-d '{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations": [
{
"op": "add",
"path": "members",
"value": [
{ "value": "USER_ID_1" },
{ "value": "USER_ID_2" }
]
}
]
}'Phản hồi lỗi SCIM
{ "schemas": ["urn:ietf:params:scim:api:messages:2.0:Error"], "status": "400", "detail": "..." }. Các mã trạng thái phổ biến bao gồm 400 (yêu cầu không hợp lệ), 404 (không tìm thấy tài nguyên), 409 (xung đột / trùng lặp) và 429 (giới hạn tốc độ).Portal API (tự động hóa)
Portal API cho phép backend của riêng bạn tự động hóa mọi thao tác bạn có thể làm trong cổng — quản lý người dùng, client, nhóm, vai trò, scope, kết nối SSO và cài đặt — bằng thông tin xác thực máy-tới-máy. Đây chính là API mà giao diện cổng gọi.
URL gốc: https://portal-api.<your-domain>/api/v1. Yêu cầu xác thực bằng access token Bearer; tenant được lấy từ token, không phải từ URL.
Tạo thông tin xác thực API
Trong cổng, mở Clients → Create API credential, chọn một cấp truy cập và đặt tên. Authagonal tạo một client OAuth client_credentials được kết nối sẵn cho Portal API và trả về một client ID cùng secret.
Sao chép secret ngay lập tức
Các cấp truy cập
| Scope | Quyền cấp |
|---|---|
tenant:owner | Toàn quyền truy cập, bao gồm các thao tác hủy hoại chỉ dành cho chủ sở hữu như xóa toàn bộ tenant. |
tenant:admin | Quản lý mọi thứ ngoại trừ các thao tác chỉ dành cho chủ sở hữu — người dùng, client, SSO, nhóm, vai trò, thương hiệu và cài đặt. |
tenant:developer | Quản lý client, scope, thương hiệu và ứng dụng cấp phát. |
tenant:support | Đọc và quản lý người dùng cho các tác vụ hỗ trợ, và đọc nhật ký kiểm toán. |
Bạn chỉ có thể cấp những gì mình đang có
Lấy token
Đổi thông tin xác thực lấy access token tại điểm cuối token của tenant quản trị của bạn — https://<your-tenant>.<your-domain>/connect/token — rồi gửi token dưới dạng header Bearer đến Portal API. Token có hiệu lực trong một giờ.
# 1. Exchange the credential for an access token (your tenant's token endpoint)
curl -X POST https://acme.authagonal.io/connect/token \
-d grant_type=client_credentials \
-d client_id=api-3f2a... \
-d client_secret=YOUR_CLIENT_SECRET \
-d scope=tenant:admin
# Response: { "access_token": "ey...", "token_type": "Bearer", "expires_in": 3600 }
# 2. Call the Portal API with the access token
curl https://portal-api.authagonal.io/api/v1/users \
-H "Authorization: Bearer $ACCESS_TOKEN"Điểm cuối
Tất cả các đường dẫn đều tương đối so với URL cơ sở và yêu cầu mã thông báo truy cập Bearer. Phạm vi (scope) bên cạnh mỗi nhóm là cấp truy cập tối thiểu mà thông tin xác thực cần. Cách phân trang khác nhau theo tài nguyên: người dùng và nhật ký kiểm toán nhận count (1 đến 200, mặc định 50) và after, đặt bằng continuationToken của phản hồi trước; nhóm nhận startIndex và count; tổ chức nhận limit và cursor; client, vai trò và scope trả về mọi hàng.
tenant:developerGET/api/v1/clientsLiệt kê các client OAuth.
GET/api/v1/clients/{id}Lấy một client theo ID.
POST/api/v1/clientsTạo một client. Trả về 201 cùng bản ghi client. Secret không được trả về ở đây: hãy tạo secret bằng POST /api/v1/clients/{clientId}/secrets, secret chỉ hiển thị một lần.
PUT/api/v1/clients/{id}Cập nhật một client (redirect URI, loại grant, thời hạn token, yêu cầu PKCE/PAR).
DELETE/api/v1/clients/{id}Xóa một client.
POST/api/v1/clients/api-credentialTạo thông tin xác thực Portal API máy-với-máy.
tenant:supportGET/api/v1/usersLiệt kê người dùng. Hỗ trợ count, search (tiền tố email hoặc tên), organizationId để lọc theo một tổ chức, và after để phân trang bằng con trỏ.
GET/api/v1/users/countTổng số người dùng của tenant.
GET/api/v1/users/stats/mfaThống kê đăng ký MFA.
GET/api/v1/users/{id}Lấy một người dùng.
POST/api/v1/users/inviteMời người dùng qua email. Tạo một tài khoản đang chờ và gửi email chứa liên kết để người được mời tự đặt mật khẩu. Các trường tùy chọn organizationId và organizationRoles cũng thêm tư cách thành viên tổ chức.
PUT/api/v1/users/{id}Cập nhật người dùng (hồ sơ, email, isActive, emailConfirmed, organizationId). Thay đổi email hoặc emailConfirmed cần tenant:admin.
DELETE/api/v1/users/{id}Xóa một người dùng.
GET/api/v1/users/{id}/mfaGet a user's enrolled MFA methods.
DELETE/api/v1/users/{id}/mfaReset a user's MFA enrollment. Needs tenant:admin.
tenant:adminGET/api/v1/rolesLiệt kê vai trò.
POST/api/v1/rolesTạo vai trò.
DELETE/api/v1/roles/{id}Xóa vai trò.
POST/api/v1/roles/assignGán vai trò cho người dùng.
POST/api/v1/roles/unassignGỡ vai trò khỏi người dùng.
tenant:adminGET/api/v1/groupsLiệt kê nhóm.
GET/api/v1/groups/{id}Lấy một nhóm cùng các thành viên.
POST/api/v1/groupsTạo nhóm.
POST/api/v1/groups/{id}/membersThêm thành viên vào nhóm.
DELETE/api/v1/groups/{groupId}/members/{userId}Gỡ một thành viên khỏi nhóm.
DELETE/api/v1/groups/{id}Xóa nhóm.
GET/api/v1/group-role-mappingsLiệt kê ánh xạ nhóm-đến-vai-trò (vai trò được cấp khi phát hành token theo tư cách thành viên nhóm).
tenant:developerGET/api/v1/scopesLiệt kê các scope API.
POST/api/v1/scopesTạo một scope.
DELETE/api/v1/scopes/{name}Xóa một scope.
tenant:adminGET/api/v1/saml/connectionsLiệt kê kết nối SAML.
POST/api/v1/saml/connectionsTạo kết nối SAML.
DELETE/api/v1/saml/connections/{id}Xóa kết nối SAML.
GET/api/v1/oidc/connectionsLiệt kê kết nối OIDC.
POST/api/v1/oidc/connectionsTạo kết nối OIDC.
DELETE/api/v1/oidc/connections/{id}Xóa kết nối OIDC.
GET/api/v1/sso/domainsLiệt kê các tên miền được định tuyến đến kết nối SSO (home-realm discovery).
tenant:developerGET/api/v1/brandingLấy thương hiệu của tenant (màu sắc, logo, ngôn ngữ được hỗ trợ).
PUT/api/v1/brandingCập nhật thương hiệu của tenant.
tenant:adminGET/api/v1/settingsLấy cài đặt tenant (webhook, đăng ký công khai, chính sách token).
PUT/api/v1/settingsCập nhật cài đặt tenant.
POST/api/v1/settings/webhook-secret/regenerateXoay secret ký webhook.
POST/api/v1/settings/test-emailGửi email thử nghiệm với cấu hình email hiện tại.
tenant:adminGET/api/v1/custom-domainsLiệt kê tên miền đăng nhập tùy chỉnh và trạng thái xác minh.
POST/api/v1/custom-domainsThêm tên miền tùy chỉnh.
POST/api/v1/custom-domains/{domain}/verifyKích hoạt xác minh DNS cho tên miền tùy chỉnh.
DELETE/api/v1/custom-domains/{domain}Gỡ tên miền tùy chỉnh.
GET/api/v1/email/domains/{domainId}Lấy các bản ghi DNS và trạng thái xác minh của một tên miền email người gửi.
tenant:supportGET/api/v1/auditTruy vấn nhật ký kiểm toán của tenant.
Cấp phát người dùng qua SCIM
Ví dụ: mời người dùng
curl -X POST https://portal-api.authagonal.io/api/v1/users/invite \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"firstName": "Ada",
"lastName": "Lovelace"
}'
# 200 OK
# { "userId": "8f3a...", "email": "[email protected]" }Bất cứ điều gì giao diện làm được
API Tổ chức
Mọi route bên dưới đều yêu cầu chính sách TenantAdmin và nằm dưới /api/v1/organizations trừ khi có ghi chú khác. Xem Portal API để biết cách tạo credential. Hai route danh sách được phân trang theo cursor: truyền limit (mặc định 50, từ 1 đến 200) và nextCursor trước đó làm cursor; chúng trả về { items, nextCursor }, và cursor sai là 400 invalid_cursor. Đối tượng tổ chức mang một danh sách domains chỉ đọc.
| Phương thức | Đường dẫn | Body | Ghi chú |
|---|---|---|---|
| GET | /api/v1/organizations | – | Một trang tổ chức theo thứ tự id. Query: cursor?, limit? (mặc định 50, từ 1 đến 200). Trả về { items, nextCursor }; nextCursor null là trang cuối. |
| POST | /api/v1/organizations | slug, name, brandingJson?, enabled?, requireMembershipForTokens?, allowAutoMembership?, metadata? | 201 + tổ chức. 409 slug_taken. |
| GET | /api/v1/organizations/{idOrSlug} | – | Tra cứu theo id trước, sau đó theo slug. |
| PUT | /api/v1/organizations/{id} | name?, brandingJson?, slug?, enabled?, requireMembershipForTokens?, allowAutoMembership?, metadata? | Chỉ các trường được nêu mới thay đổi. Slug khác bị từ chối: nó bất biến sau khi tạo. domains không thể thay đổi tại đây. |
| DELETE | /api/v1/organizations/{id} | – | Xóa mọi tư cách thành viên của tổ chức trước, sau đó xóa chính tổ chức. |
| GET | /api/v1/organizations/{id}/members | – | Một trang tư cách thành viên theo thứ tự id người dùng, với e-mail/tên hiện tại của thành viên được lấy từ kho người dùng. Query: cursor?, limit?. |
| POST | /api/v1/organizations/{id}/members | userId? | email?, status?, roles? | 201 + tư cách thành viên. 404 user_not_found. 409 membership_exists. Các vai trò dành riêng tenant:* và platform:* bị từ chối với 400 invalid_role, không bị loại bỏ lặng lẽ. |
| PUT | /api/v1/organizations/{id}/members/{userId} | status?, roles? | Đặt status thành active sẽ đóng dấu joinedAt nếu nó chưa được đặt. |
| DELETE | /api/v1/organizations/{id}/members/{userId} | – | Gỡ hẳn dòng, không phải thay đổi trạng thái. |
| POST | /api/v1/organizations/{id}/domains | domain | Khai báo một tên miền e-mail, chưa xác minh. 201 + { domain, verified, verifiedAt, createdAt, recordName, recordValue }. 400 domain_invalid. 409 domain_exists, domain_taken. |
| POST | /api/v1/organizations/{id}/domains/{domain}/verify | – | Tra cứu bản ghi TXT tại recordName và khớp chính xác recordValue. 200 + tên miền khi đã xác minh (lặp lại là 200 không có tác dụng); 409 verification_failed khi không khớp; 409 domain_taken; 404 domain_not_found. |
| DELETE | /api/v1/organizations/{id}/domains/{domain} | – | 204. Bỏ khai báo, dù đã xác minh hay chưa. Các thành viên hiện có được giữ nguyên. 404 domain_not_found. |
| POST | /api/v1/organizations/backfill | dryRun? = true | Chuyển thẻ AuthUser.organizationId cũ thành các dòng Organization/OrganizationMembership thực. |
| GET | /api/v1/users/{userId}/organizations | – | Mọi tổ chức mà người dùng này thuộc về, kèm trạng thái/vai trò của họ trong từng tổ chức. |
Màn hình đăng nhập
Đây là những màn hình được lưu trữ mà người dùng cuối của bạn nhìn thấy trên máy chủ auth của tenant. Authagonal cung cấp sẵn mọi màn hình để dùng ngay, nên bạn có được trải nghiệm đăng nhập hoàn chỉnh, an toàn mà không cần xây dựng bất kỳ giao diện nào. Trang này đi qua từng màn hình và chỉ ra những cài đặt portal nào điều khiển nó.
White-label hoàn toàn
prefers-color-scheme, nên chúng chuyển đổi giữa chế độ sáng và tối để phù hợp với thiết bị của người dùng.Đăng nhập


- Luồng hai bước, ưu tiên email: người dùng nhập email và nhấn Tiếp tục, sau đó trường mật khẩu xuất hiện.
- Các nút đăng nhập một lần "Tiếp tục với {provider}" xuất hiện tự động khi có kết nối SSO.
- Liên kết quên mật khẩu và tạo tài khoản, mỗi liên kết có thể hiển thị hoặc ẩn.
- Tùy chọn captcha Cloudflare Turnstile để ngăn chặn các nỗ lực đăng nhập tự động.
Được điều khiển trong phần quản trị portal
- Branding thiết lập logo, màu sắc, tên ứng dụng, email hỗ trợ và CSS tùy chỉnh.
- Hiển thị hoặc ẩn liên kết quên mật khẩu và đăng ký (Branding).
- Kết nối SSO thêm các nút đăng nhập mạng xã hội (trang SSO).
- Thời lượng phiên và ngưỡng khóa tài khoản (Cài đặt → Phiên).
Đăng ký


- Thu thập họ và tên (tùy chọn), email và một mật khẩu.
- Một danh sách kiểm tra chính sách mật khẩu trực tiếp cập nhật khi người dùng gõ, nên các yêu cầu được rõ ràng trước khi gửi.
- Tùy chọn captcha Cloudflare Turnstile.
- Một liên kết "Đăng nhập" cho người dùng đã có tài khoản.
Được điều khiển trong phần quản trị portal
- Hiển thị hoặc ẩn liên kết đăng ký (Thương hiệu). Để tắt hoàn toàn việc đăng ký, hãy tắt Cho phép đăng ký công khai (Cài đặt → Phiên).
- Chính sách mật khẩu của tenant điều khiển danh sách kiểm tra.
- Branding tạo kiểu cho toàn bộ màn hình.
Quên mật khẩu


- Người dùng nhập email của họ, sau đó thấy một xác nhận trung lập "hãy kiểm tra email của bạn".
- Màn hình không bao giờ tiết lộ liệu một tài khoản có tồn tại hay không, điều này vô hiệu hóa việc dò tìm liệt kê tài khoản.
- Một liên kết "Quay lại đăng nhập" đưa người dùng trở về màn hình đăng nhập.
Được điều khiển trong phần quản trị portal
- Hiển thị hoặc ẩn liên kết quên mật khẩu (Branding).
- Gửi email của tenant gửi đi thông điệp đặt lại.
- Branding tạo kiểu cho toàn bộ màn hình.
Đặt lại mật khẩu


- Các trường mật khẩu mới và xác nhận mật khẩu với một danh sách kiểm tra yêu cầu theo từng quy tắc trực tiếp.
- Một trạng thái liên kết không hợp lệ hoặc đã hết hạn rõ ràng khi token đặt lại không còn hiệu lực.
- Một trạng thái thành công xác nhận mật khẩu đã được thay đổi.
Được điều khiển trong phần quản trị portal
- Chính sách mật khẩu của tenant điều khiển danh sách kiểm tra.
- Branding tạo kiểu cho toàn bộ màn hình.
Thử thách MFA


- Một bộ chuyển phương thức giữa ứng dụng xác thực, passkey và mã khôi phục.
- Một trường TOTP 6 chữ số tự động gửi khi nhập đủ các chữ số.
- Nhập mã khôi phục cho người dùng đã mất quyền truy cập vào ứng dụng xác thực của họ.
- Một nút passkey để xác minh dựa trên phần cứng.
Được điều khiển trong phần quản trị portal
- Chính sách MFA được thiết lập theo từng ứng dụng (Clients → Bảo mật).
- Bất kỳ người dùng nào đã đăng ký một yếu tố đều luôn bị thử thách, bất kể chính sách.
Thiết lập MFA


- Hiển thị trạng thái của các phương thức đã đăng ký để người dùng biết những gì đã được cấu hình.
- Thiết lập ứng dụng xác thực qua mã QR, một khóa nhập thủ công dự phòng và một bước xác nhận.
- Đăng ký passkey để xác thực dựa trên phần cứng.
- Tạo mã khôi phục để khôi phục tài khoản.
- Một tùy chọn bỏ qua khi MFA là tự phục vụ thay vì bắt buộc.
Được điều khiển trong phần quản trị portal
- Chính sách MFA được thiết lập theo từng ứng dụng; Bắt buộc buộc thiết lập khi đăng nhập (Clients → Bảo mật).
- Branding tạo kiểu cho toàn bộ màn hình.
Ủy quyền thiết bị


- Một trường nhập mã người dùng căn giữa cho mã hiển thị trên thiết bị.
- Một bước phê duyệt để ủy quyền thiết bị.
- Một màn hình chuyển tiếp đăng nhập khi người dùng chưa được xác thực.
- Một xác nhận đã phê duyệt khi thiết bị đã được ủy quyền.
Được điều khiển trong phần quản trị portal
- Bật device-code grant trên ứng dụng (Clients → Scopes & Grants).
- Thiết lập thời lượng device-code (Clients → Token).
Đồng ý


- Hiển thị logo và tên của client đang yêu cầu.
- Một danh sách theo từng scope với nhãn thân thiện, dễ đọc cho mỗi quyền.
- Các nút Cho phép và Từ chối để cấp hoặc khước từ quyền truy cập.
- Một chân trang gợi ý đồng ý giải thích quyết định đó có ý nghĩa gì.
Được điều khiển trong phần quản trị portal
- Bật Yêu cầu đồng ý theo từng ứng dụng (Clients → Chung).
- Logo, tên và URL đến từ chính metadata của ứng dụng.
- Branding tô vẽ thẻ đồng ý.
Ứng dụng đã kết nối (grant)


- Liệt kê mọi ứng dụng mà người dùng đã ủy quyền, cùng với tên, scope và ngày cấp của nó.
- Thu hồi quyền truy cập vào một ứng dụng, với một bước xác nhận trước khi có hiệu lực.
- Một trạng thái trống thân thiện khi người dùng chưa ủy quyền cho ứng dụng nào.
Được điều khiển trong phần quản trị portal
- Danh sách được điền bởi các ứng dụng yêu cầu đồng ý.
- Branding tạo kiểu cho toàn bộ màn hình.
Tài khoản
Một trang tài khoản tự phục vụ được lưu trữ tại /login/account, nơi người dùng đã đăng nhập quản lý hồ sơ và ngôn ngữ ưu tiên của riêng họ, không cần quyền truy cập portal.


- Chỉnh sửa họ và tên, công ty và điện thoại; địa chỉ e-mail hiển thị ở chế độ chỉ đọc.
- Chọn một ngôn ngữ ưu tiên trong số các ngôn ngữ được hỗ trợ; giao diện xem trước lựa chọn ngay lập tức và lưu lại khi nhấn lưu.
- Ngôn ngữ đã lưu điều khiển giao diện được lưu trữ của người dùng và ngôn ngữ của các e-mail giao dịch mà họ nhận được.
Được điều khiển trong phần quản trị portal
- Branding tạo kiểu cho toàn bộ màn hình.
- Cùng một ngôn ngữ ưu tiên cũng có thể được quản trị viên chỉnh sửa trên trang Người dùng của portal.
Luồng xác thực
Luồng xác thực bao gồm cách người dùng cuối tương tác với tenant Authagonal — đăng nhập, đăng ký, đặt lại mật khẩu và thiết lập MFA. Các điểm cuối này được sử dụng bởi trang đăng nhập được lưu trữ và có thể được gọi trực tiếp nếu bạn đang xây dựng giao diện đăng nhập tùy chỉnh.
Đăng nhập
POST /api/auth/login
Xác thực người dùng bằng email và mật khẩu. Khi thành công, ký cookie phiên và trả về hồ sơ người dùng. Nếu MFA được cấu hình, phản hồi cho biết yếu tố thứ hai được yêu cầu trước khi phiên được thiết lập hoàn toàn.
Phần thân yêu cầu:
{
"email": "[email protected]",
"password": "correct-horse-battery-staple"
}Phản hồi thành công:
| Trường | Loại | Mô tả |
|---|---|---|
userId | string | Mã định danh người dùng duy nhất |
email | string | Địa chỉ email người dùng |
name | string | Tên hiển thị đầy đủ |
mfaAvailable | boolean | Người dùng đã đăng ký phương thức MFA hay chưa |
Phản hồi yêu cầu MFA: Khi người dùng đã đăng ký MFA, phản hồi bao gồm mfaRequired: true cùng với challengeId và mảng methods liệt kê các phương thức MFA khả dụng.
Phản hồi yêu cầu thiết lập MFA: Khi chính sách MFA của ứng dụng là Bắt buộc nhưng người dùng chưa đăng ký, phản hồi bao gồm mfaSetupRequired: true với setupToken cho luồng đăng ký.
Phản hồi lỗi:
| Mã lỗi | Mã trạng thái HTTP | Mô tả |
|---|---|---|
invalid_credentials | 401 | Email hoặc mật khẩu không chính xác |
account_disabled | 403 | Tài khoản đã bị vô hiệu hóa bởi quản trị viên |
email_not_confirmed | 403 | Người dùng chưa xác minh địa chỉ email |
locked_out | 423 | Tài khoản tạm thời bị khóa (bao gồm retryAfter tính bằng giây). Chỉ trả về khi mật khẩu đúng; nhập sai mật khẩu trong khi bị khóa sẽ trả về invalid_credentials |
sso_required | 409 | Tên miền email đã cấu hình SSO (bao gồm redirectUrl) |
too_many_attempts | 429 | Quá nhiều lần đăng nhập từ IP này hoặc cho email này; hãy thử lại sau |
captcha_failed | 400 | Thử thách Turnstile thất bại hoặc bị thiếu (chỉ khi Turnstile được bật) |
Kiểm tra SSO: Nếu tên miền email của người dùng đã cấu hình kết nối SSO, điểm cuối đăng nhập trả về sso_required với redirectUrl. Client nên chuyển hướng người dùng đến nhà cung cấp SSO.
Khóa tài khoản: Sau maxFailedAttempts lần đăng nhập thất bại liên tiếp, tài khoản bị khóa trong lockoutDurationMinutes. Cả hai giá trị đều có thể cấu hình trong cài đặt tenant.
Trang đăng nhập được lưu trữ
Đăng ký
POST /api/auth/register
Tạo tài khoản người dùng mới và gửi email xác minh. Khi <strong>Yêu cầu xác minh email để đăng nhập</strong> (Cài đặt → Phiên) đang bật, đây là mặc định, người dùng phải xác minh email trước khi đăng nhập.
Phần thân yêu cầu:
{
"email": "[email protected]",
"password": "a-strong-password-here",
"firstName": "Jane",
"lastName": "Smith"
}| Trường | Bắt buộc | Mô tả |
|---|---|---|
email | Có | Địa chỉ email (phải là duy nhất) |
password | Có | Phải đáp ứng chính sách mật khẩu tenant |
firstName | Không | Tên |
lastName | Không | Họ |
Thành công: 201 Created với userId của tài khoản mới. Đăng ký bằng email đã tồn tại cũng trả về 201: chúng tôi không bao giờ tiết lộ một email có tồn tại hay không (để ngăn việc dò tìm tài khoản), mà thay vào đó thông báo cho chủ tài khoản thực sự qua email.
Phản hồi lỗi:
| Mã lỗi | Mã trạng thái HTTP | Mô tả |
|---|---|---|
weak_password | 400 | Mật khẩu không đáp ứng chính sách mật khẩu tenant |
rate_limited | 429 | Quá nhiều lần đăng ký |
provisioning_rejected | 422 | Webhook cung cấp đã từ chối đăng ký |
invalid_email | 400 | Địa chỉ email không hợp lệ |
captcha_failed | 400 | Thử thách Turnstile thất bại hoặc bị thiếu (chỉ khi Turnstile được bật) |
public_signup_disabled | 403 | Đăng ký công khai đã bị tắt cho tenant này (Cài đặt → Phiên) |
Chính sách mật khẩu
/api/auth/password-policy. Trả về danh sách rules: độ dài tối thiểu và các lớp ký tự bắt buộc.Đặt lại mật khẩu
POST /api/auth/forgot-password
Yêu cầu email đặt lại mật khẩu. Điểm cuối luôn trả về phản hồi thành công bất kể email có tồn tại hay không, để ngăn chặn liệt kê email.
{
"email": "[email protected]"
}POST /api/auth/reset-password
Đặt lại mật khẩu người dùng bằng token từ liên kết email.
{
"token": "RESET_TOKEN_FROM_EMAIL",
"newPassword": "new-strong-password"
}Tác dụng phụ của việc đặt lại mật khẩu thành công:
- Bộ đếm đăng nhập thất bại được đặt lại về không
- Tất cả refresh token hiện có bị thu hồi
- Dấu bảo mật mới được tạo (vô hiệu hóa tất cả phiên hiện có)
Thiết lập & Xác minh MFA
Authagonal hỗ trợ ba phương thức MFA: TOTP (ứng dụng xác thực), WebAuthn (khóa bảo mật và sinh trắc học) và mã khôi phục dùng một lần.
Thiết lập TOTP
POST /api/auth/mfa/totp/setup: Trả về <code>setupToken</code>, URI dữ liệu mã QR và khóa nhập thủ công. Người dùng quét mã QR bằng ứng dụng xác thực (Google Authenticator, Authy, 1Password, v.v.), sau đó xác nhận đăng ký.
POST /api/auth/mfa/totp/confirm: Xác nhận đăng ký TOTP bằng cách gửi <code>setupToken</code> từ bước thiết lập cùng với mã 6 chữ số từ ứng dụng xác thực.
{
"setupToken": "SETUP_TOKEN_FROM_SETUP_RESPONSE",
"code": "123456"
}Thiết lập WebAuthn
POST /api/auth/mfa/webauthn/setup — Trả về tùy chọn tạo thông tin xác thực cho WebAuthn API. Trình duyệt gọi navigator.credentials.create() với các tùy chọn này.
POST /api/auth/mfa/webauthn/confirm: Xác nhận đăng ký WebAuthn bằng cách gửi phản hồi chứng thực từ trình duyệt.
Mã khôi phục
POST /api/auth/mfa/recovery/generate: Tạo 10 mã khôi phục dùng một lần gồm 10 ký tự (định dạng <code>XXXXX-XXXXX</code>). Mỗi mã chỉ có thể sử dụng một lần để bỏ qua MFA. Phải đăng ký ứng dụng xác thực hoặc passkey trước.
Mã khôi phục chỉ hiển thị một lần
Xác minh MFA
POST /api/auth/mfa/verify: Hoàn thành thử thách MFA sau khi đăng nhập bằng mật khẩu thành công.
| Trường | Bắt buộc | Mô tả |
|---|---|---|
challengeId | Có | ID thử thách từ phản hồi đăng nhập |
method | Có | "totp", "recovery" hoặc "webauthn" |
code | TOTP / Mã khôi phục | Mã TOTP 6 chữ số hoặc mã khôi phục (XXXXX-XXXXX) |
assertion | WebAuthn | Phản hồi assertion từ navigator.credentials.get() |
Trạng thái MFA
GET /api/auth/mfa/status: Trả về các phương thức MFA hiện đã đăng ký của người dùng.
Luồng đăng nhập SSO
Authagonal hỗ trợ cả kết nối SSO dựa trên SAML 2.0 và OIDC. Định tuyến theo tên miền tự động phát hiện nhà cung cấp SSO nào sử dụng dựa trên địa chỉ email người dùng.
Kiểm tra SSO
GET /api/auth/[email protected]
| Trường | Loại | Mô tả |
|---|---|---|
ssoRequired | boolean | Tên miền email có yêu cầu SSO hay không |
providerType | string | "saml" hoặc "oidc" |
connectionId | string | Mã định danh kết nối SSO |
redirectUrl | string | URL chuyển hướng người dùng để đăng nhập SSO |
Luồng SAML
Người dùng được chuyển hướng đến GET /saml/{connectionId}/login gửi SAML AuthnRequest đến nhà cung cấp danh tính. IdP xác thực người dùng và gửi phản hồi SAML trở lại điểm cuối Assertion Consumer Service (ACS). Authagonal xác thực assertion, tạo hoặc cập nhật người dùng và ký cookie phiên.
SAML metadata để cấu hình IdP có sẵn tại GET /saml/{connectionId}/metadata.
Luồng OIDC
Người dùng được chuyển hướng đến GET /oidc/{connectionId}/login chuyển hướng đến nhà cung cấp danh tính upstream với PKCE. Sau khi người dùng xác thực, callback tại /oidc/callback trao đổi mã ủy quyền, xác thực ID token và tạo hoặc cập nhật người dùng.
Cung cấp JIT: Cả luồng SAML và OIDC đều hỗ trợ cung cấp just-in-time, tính năng này mặc định bị tắt trên mỗi kết nối (Bật cấp tài khoản JIT). Khi được bật và người dùng chưa tồn tại trong tenant, họ được tạo tự động từ claims của nhà cung cấp danh tính. Nếu đã tồn tại, thuộc tính hồ sơ được cập nhật để khớp với giá trị mới nhất từ nhà cung cấp.
Định tuyến theo tên miền
Backend-for-Frontend (BFF)
BFF giữ token OAuth hoàn toàn bên ngoài trình duyệt. Ứng dụng single-page (SPA) của bạn chỉ giữ duy nhất một cookie phiên httpOnly, còn một confidential client trên backend của chính bạn thực hiện luồng OpenID Connect và giữ token ở phía máy chủ.
Bất cứ thứ gì ứng dụng single-page đọc được thì cross-site scripting cũng lấy được, kể cả một access token trong bộ nhớ và một refresh token trong localStorage. Lưu token trong trình duyệt cũng buộc phải rút ngắn thời gian sống của chúng, vì một refresh token dài hạn nằm trong tầm với của script là một rủi ro thường trực. Tài liệu best current practice OAuth 2.0 for Browser-Based Apps của IETF khuyến nghị mô hình này chính vì lý do đó.
Đổi lại, bạn có một phiên sống sót qua việc tải lại trang mà không cần token nào lộ diện, việc làm mới token được xử lý sẵn ở phía máy chủ, thu hồi tức thì qua back-channel logout, và một proxy đã xác thực để API của bạn không bao giờ phải phân tích một token mà trình duyệt có thể đã can thiệp.
Tạo client
Trong cổng, mở Clients và chọn Tạo ứng dụng BFF. Nhập base URL mà ứng dụng của bạn được phục vụ từ đó, ví dụ https://app.acme.com, và Authagonal sẽ đăng ký sẵn cho bạn một confidential client được cấu hình đúng, thay vì để bạn tự ráp lấy:
| Cài đặt | Giá trị |
|---|---|
| URI chuyển hướng | {appBaseUrl}/bff/callback |
| URI chuyển hướng sau đăng xuất | {appBaseUrl}/ |
| URI back-channel logout | {appBaseUrl}/bff/backchannel-logout |
| Loại cấp quyền | authorization_code, refresh_token |
| Scope | openid, profile, email, offline_access |
| PKCE và client secret | Cả hai đều bắt buộc |
Khóa bí mật chỉ hiển thị một lần
clientId, clientSecret và authority, và sau đó khóa bí mật không bao giờ lấy lại được, vì chỉ mã băm của nó được lưu. Hãy đưa thẳng nó vào cấu hình hoặc kho bí mật của backend. Nếu làm mất, hãy tạo một client khác thay vì cố khôi phục client này.Đấu nối vào backend của bạn
Hai runtime được hỗ trợ và dùng chung cùng một giao thức lõi: Authagonal.Bff cho .NET và @authagonal/bff cho Node, gói sau có sẵn adapter cho Express và Next.js. Hãy trỏ gói bạn chọn tới đúng các giá trị mà cổng vừa cấp cho bạn. Gói Node còn cần một cookieSecret của riêng bạn, dùng để mã hóa cookie của nó.
// dotnet add package Authagonal.Bff
builder.Services.AddAuthagonalBff(o =>
{
o.Authority = "https://acme.authagonal.io"; // your tenant auth host
o.ClientId = builder.Configuration["Bff:ClientId"]!;
o.ClientSecret = builder.Configuration["Bff:ClientSecret"]!;
o.Scope = ["openid", "profile", "email", "offline_access"];
o.PostLogoutRedirectUri = "https://app.acme.com/";
});
// Trust X-Forwarded-Proto from your ingress. With no options, UseForwardedHeaders() changes nothing.
builder.Services.Configure<ForwardedHeadersOptions>(o =>
{
o.ForwardedHeaders = ForwardedHeaders.XForwardedProto;
o.KnownNetworks.Clear();
o.KnownProxies.Clear();
});
var app = builder.Build();
app.UseForwardedHeaders(); // required behind a proxy or ingress, see the note below
app.MapAuthagonalBff();
app.MapFallbackToFile("index.html"); // your SPA
app.Run();// npm install @authagonal/bff
import express from 'express';
import { authagonalBff } from '@authagonal/bff/express';
const app = express();
app.use(authagonalBff({
authority: 'https://acme.authagonal.io',
clientId: process.env.BFF_CLIENT_ID,
clientSecret: process.env.BFF_CLIENT_SECRET,
cookieSecret: process.env.BFF_COOKIE_SECRET, // encrypts the session and login cookies
scope: ['openid', 'profile', 'email', 'offline_access'],
postLogoutRedirectUri: 'https://app.acme.com/',
}));
app.listen(8080);Sau proxy, hãy tin các header được chuyển tiếp
__Host- mà thiếu thuộc tính Secure, rồi trình duyệt lặng lẽ loại bỏ nó. Triệu chứng là một lần đăng nhập hoàn tất trơn tru nhưng phiên thì không bao giờ xuất hiện. Trong .NET, hãy bật XForwardedProto trong ForwardedHeadersOptions và gọi app.UseForwardedHeaders() trước MapAuthagonalBff(), như ở trên: lời gọi không kèm cấu hình sẽ không tin cậy header nào. Các adapter Node tự đọc X-Forwarded-Proto và luôn đánh dấu cookie __Host- là Secure; hãy đặt cài đặt trust-proxy của framework để địa chỉ client được chuyển tiếp tới API của bạn là địa chỉ thật.Điểm cuối
Mặc định được gắn dưới /bff. Chúng phải được phục vụ từ cùng origin với SPA của bạn, vì cookie phiên là httpOnly và same-origin: hãy đặt chúng sau cùng một hostname thay vì trên một tên miền API riêng.
| Đường dẫn | Mục đích |
|---|---|
GET /bff/login?returnUrl=/ | Bắt đầu đăng nhập và chuyển hướng tới Authagonal. Sau đó đưa người dùng trở lại returnUrl. |
GET /bff/callback | URI chuyển hướng OIDC. Được xử lý sẵn cho bạn; bạn không bao giờ phải tự viết phần này. |
GET /bff/user | Trả về isAuthenticated, các claim của phiên và sessionExpiresAt. Yêu cầu header chống giả mạo. |
GET|POST /bff/logout | Kết thúc phiên tại chỗ và tại Authagonal. |
POST /bff/backchannel-logout | Nhận thông báo đăng xuất từ Authagonal, nên một lần đăng xuất ở nơi khác cũng kết thúc phiên này. |
Từ trình duyệt
Mọi yêu cầu không phải điều hướng đều phải mang một header chống giả mạo cố định. Nó chống cross-site request forgery cùng với thuộc tính SameSite của cookie: một form post từ site khác không thể đặt header tùy chỉnh, nên yêu cầu thiếu header đó sẽ bị từ chối.
const me = await fetch('/bff/user', {
headers: { 'X-Authagonal-Bff': '1' },
}).then(r => r.json());
if (!me.isAuthenticated) {
// Navigate, do not fetch: this is a redirect to your identity provider.
window.location.href = '/bff/login?returnUrl=' + encodeURIComponent(location.pathname);
}Hãy đăng nhập và đăng xuất bằng cách điều hướng, chứ không phải fetch: location.href = '/bff/login'. Các route đó trả lời bằng một chuyển hướng tới nhà cung cấp danh tính của bạn, và fetch không thể theo một chuỗi chuyển hướng như vậy một cách hữu ích.
Gọi API của bạn
BFF có thể chuyển tiếp API của bạn dưới base path của chính nó và gắn access token của phiên trên đường đi. Trình duyệt gửi một cookie, API của bạn nhận một bearer token và xác thực nó như bình thường, còn trang web thì không nhìn thấy và cũng không giả mạo được bất cứ điều gì về token đó. Hãy đăng ký một upstream và các yêu cầu tới /bff/api/** sẽ đến đó ở trạng thái đã xác thực. Để danh sách trống thì proxy bị tắt hoàn toàn.
o.Upstreams.Add(new BffUpstream
{
Prefix = "/orders", // matches /bff/api/orders/**
TargetBaseUrl = "https://api.internal.acme.com",
StripPrefix = false, // keep /orders in the forwarded path
});| Tùy chọn | Mặc định | Mô tả |
|---|---|---|
Upstreams | [] | Các API mà proxy chuyển tiếp tới. Để trống thì điểm cuối proxy bị tắt. |
Prefix | / | Tiền tố đường dẫn sau /bff/api mà upstream này xử lý, ví dụ /orders. |
TargetBaseUrl | - | Base URL mà các yêu cầu được chuyển tiếp tới. |
StripPrefix | false | Bỏ tiền tố đã khớp trước khi chuyển tiếp. Cho phép bạn dùng một tiền tố định tuyến nhân tạo để tỏa một BFF ra nhiều backend cùng chia sẻ một không gian tên đường dẫn. |
AllowAnonymousProxyRequests | false | Chuyển tiếp một yêu cầu không có phiên dùng được mà không kèm header Authorization, thay vì từ chối nó. Dành cho một API phục vụ cả người gọi đã đăng nhập lẫn người gọi ẩn danh. |
RequiredAuthority | [] | Một rào chắn quyền hạn dưới dạng các cặp type:action, ví dụ email:send. Khi được đặt, proxy kiểm tra authorization details theo RFC 9396 của token đi ra trước khi chuyển tiếp. |
AuthorityLocation | - | Gốc locations theo RFC 9396 mà upstream này được biết tới, khi quyền được cấp cho một định danh tài nguyên công khai khác với địa chỉ nội bộ mà proxy gọi. |
StrictAuthority | false | Từ chối một lệnh gọi mang ràng buộc grant mà proxy không đánh giá được, thay vì chuyển tiếp nó. Proxy chuyển tiếp một cách mù và không suy ra ngữ cảnh ràng buộc nào, nên mặc định tùy chọn này tắt. |
ExchangeRoutes | [] | Các route proxy mà lệnh gọi upstream đi kèm một token đã trao đổi và gắn với ngữ cảnh, thay vì access token chính của phiên. Mẫu khớp đầu tiên thắng. |
WebSockets
Một lần bắt tay WebSocket không thể mang header tùy chỉnh hay bearer token, nên cả header chống giả mạo lẫn proxy đều không giúp được gì. Hãy bật vé và SPA có thể gọi GET /bff/ws-ticket, đặt chiếc vé dùng một lần, sống ngắn đó lên URL kết nối, rồi để API của bạn đổi vé. Hãy phát vé ngay trước mỗi lần kết nối: vé bị xóa ở lần dùng đầu tiên và hết hạn sau vài giây.
| Tùy chọn | Mặc định | Mô tả |
|---|---|---|
WsTicketsEnabled | false | Bật điểm cuối ws-ticket. Mặc định tắt. |
WsTicketLifetime | 30s | Một chiếc vé có hiệu lực bao lâu. Được giữ ngắn một cách có chủ đích, vì nó đi trong URL. |
TicketExchangeParams | [] | Các tham số truy vấn mà một yêu cầu vé có thể chuyển tiếp vào một lần trao đổi token, để chiếc vé gắn với ngữ cảnh đó thay vì có hiệu lực cho mọi thứ. |
Trao token cho trình duyệt, một cách có chủ đích
Toàn bộ ý nghĩa của một BFF là trình duyệt không giữ token nào, nên tính năng này phải tự bật và có phạm vi hẹp. Nó tồn tại cho đúng một trường hợp mà mô hình cookie không với tới được: một resource server nằm trên origin khác, chẳng hạn một ứng dụng bạn nhúng trong iframe, phải được gọi bằng bearer. Khi bật, GET /bff/token?resource=… trả về một token đã trao đổi: token của phiên được thu hẹp phạm vi xuống đúng một tài nguyên trong danh sách cho phép và gắn với những tham số ngữ cảnh có trong danh sách cho phép. Trình duyệt không bao giờ thấy token của chính phiên, và thứ nó nhận được thì sống ngắn và chỉ dành cho một audience. Một yêu cầu nêu tên tài nguyên ngoài danh sách cho phép sẽ bị từ chối, và đó chính là điều ngăn tính năng này trở thành một cỗ máy phát token đa dụng.
| Tùy chọn | Mặc định | Mô tả |
|---|---|---|
TokenEndpointEnabled | false | Bật điểm cuối token. Mặc định tắt. |
TokenEndpointResources | [] | Các giá trị resource mà một token có thể được cấp cho. Mọi giá trị khác đều bị từ chối. |
TokenEndpointExchangeParams | [] | Các tham số truy vấn được chuyển tiếp vào lần trao đổi dưới dạng ràng buộc ngữ cảnh, ví dụ project_id. |
Phục vụ nhiều tenant từ một BFF
Đặt một tham số truy vấn tenant và một bản triển khai phục vụ được nhiều tenant: /bff/login?slug=acme chọn tenant, một resolver cung cấp authority và thông tin đăng nhập client của tenant đó, khóa đi theo cookie correlation vào trong phiên, và back-channel logout xác định tenant từ issuer của token. Resolver mặc định giữ hành vi đơn tenant giống hệt tới từng byte, nên bạn không phải trả giá gì cho tính năng này trừ khi dùng đến.
Chạy nhiều hơn một instance
Phiên nằm sau IBffSessionStore, mặc định là một cache trong tiến trình. Điều đó ổn với một instance duy nhất và sai với nhiều instance: người dùng có yêu cầu tiếp theo rơi vào một replica khác sẽ bị đăng xuất. Hãy đăng ký một kho lưu trữ dùng chung, ví dụ Redis qua IDistributedCache, trước khi thêm BFF.
Chỉ một kho lưu trữ dùng chung thôi là chưa đủ
ILeaseProvider thông qua clustering, hoặc hiện thực IBffRefreshLockStore trên kho phiên của bạn, vốn chỉ là một thao tác ghi có điều kiện kèm thời gian sống và là đường ngắn hơn khi bạn đã chạy Redis. Một BFF có kho lưu trữ trông như dùng chung mà không có khóa sẽ cảnh báo ngay lúc khởi động, thay vì để bạn phát hiện ra từ một yêu cầu hỗ trợ.Những tùy chọn đáng biết
Danh sách đầy đủ, theo cách viết của .NET. Gói Node nhận các tùy chọn lõi ở dạng camelCase, nên BasePath là basePath và SessionLifetime là sessionLifetimeSeconds. PersistentCookie, CorrelationLifetime (cố định 15 phút trong Node) và LoginPassthroughParams chỉ có trong .NET.
| Tùy chọn | Mặc định | Mô tả |
|---|---|---|
Authority | - | Máy chủ auth của tenant bạn. Metadata OIDC được khám phá từ đó. Bắt buộc, trừ khi bạn chạy đa tenant, khi ấy resolver sẽ cung cấp giá trị này. |
ClientId | - | Id của confidential client đã đăng ký cho BFF này. |
ClientSecret | - | Client secret. BFF là một confidential client, nên giá trị này là bắt buộc. |
Scope | openid profile offline_access | Các scope được yêu cầu. Hãy đưa offline_access vào, nếu không sẽ không có refresh token và phiên sẽ kết thúc cùng lúc với access token. |
BasePath | /bff | Nơi các route của BFF được gắn vào. |
CallbackPath | /bff/callback | Đường dẫn URI chuyển hướng OIDC. Phải khớp với giá trị mà client đã đăng ký. |
CookieName | __Host-agbff | Tên cookie phiên. Tiền tố __Host- đòi hỏi HTTPS, nên khi phát triển cục bộ trên HTTP thuần bạn cần một tên khác. |
SessionLifetime | 8h | Một phiên được sống bao lâu. Hãy đặt trùng với thời gian sống tuyệt đối của refresh token, nếu không một người dùng đang nhàn rỗi sẽ bị đăng xuất trong khi vẫn đang giữ một thông tin xác thực còn hiệu lực. |
PersistentCookie | false | Cookie có tồn tại sau khi đóng trình duyệt hay không. Dù thế nào thì refresh token vẫn nằm ở phía máy chủ. |
CorrelationLifetime | 30m | Một lần đăng nhập được phép kéo dài bao lâu, tính từ lúc bắt đầu tới lúc callback. Nó giới hạn cookie mang state, nonce và PKCE verifier, nên trường hợp mà nó phải chịu được là người dùng để mở màn hình đăng nhập rồi quay lại sau. |
RefreshThresholdSeconds | 60 | Access token được làm mới trước thời điểm hết hạn bao nhiêu giây. |
AntiForgeryHeader | X-Authagonal-Bff | Tên header mà trình duyệt phải gửi trên các yêu cầu không phải điều hướng. |
PostLogoutRedirectUri | - | Nơi trình duyệt dừng lại sau khi đăng xuất hoàn tất. |
ReturnUrlAllowlist | [] | Các origin tuyệt đối mà một returnUrl không tương đối được phép trỏ tới. Đường dẫn tương đối thì luôn được phép và mọi thứ khác bị ép về /, nên không thể tạo ra open redirect qua route đăng nhập. |
LoginPassthroughParams | [] | Các tham số truy vấn được chuyển tiếp từ /bff/login sang yêu cầu authorize, ví dụ prompt, để một liên kết bắt đầu dùng thử có thể dẫn tới trang đăng ký thay vì trang đăng nhập. |
TenantQueryParam | - | Đặt giá trị này để phục vụ nhiều tenant từ một BFF. Xem phần trên. |
Hai runtime hoạt động như nhau
StripPrefix, các cổng kiểm tra authority và proxy ẩn danh chỉ có trong .NET. Các tên ở trên là cách viết của .NET; Node dùng các tên tương đương ở dạng camelCase.Mọi thành phần đều thay thế được
IBffSessionStore cho nơi lưu phiên, ICookieProtector cho việc mã hóa cookie (mặc định là ASP.NET Data Protection), và ITokenClient để làm việc với các điểm cuối token và thu hồi. Một BFF cũng có thể phục vụ nhiều tenant thông qua IBffTenantResolver, chọn tenant từ một tham số truy vấn lúc đăng nhập và xác định lại tenant từ issuer của token khi back-channel logout.Điều hành cổng quản lý bằng một trợ lý AI
Kết nối một trợ lý AI với tenant của bạn và nhờ nó làm những việc mà bạn vẫn phải bấm chuột từng bước để làm: tìm một người dùng không đăng nhập được, kiểm tra xem họ còn yếu tố thứ hai hay không, mời ai đó, xem ai đang giữ vai trò quản trị.
Đây là một kết nối OAuth bình thường, không phải một khóa API. Mỗi người tự đăng nhập bằng danh tính của chính mình và phê duyệt quyền truy cập, nên một trợ lý làm được đúng những gì người đó làm được trong cổng quản lý, không hơn. Không có thứ gì mới được tạo ra để có thể rò rỉ, và thu hồi một trợ lý không đụng tới bất kỳ trợ lý nào khác.
Bật tính năng
Mở Cài đặt và bật quyền truy cập cho trợ lý AI. Trước khi bạn bật, tính năng này tắt, và trong lúc tắt thì endpoint không tồn tại chứ không chỉ đơn thuần từ chối. Sau khi bật, bảng cài đặt sẽ hiển thị URL để bạn dán vào client AI của mình:
https://portal-api.authagonal.io/api/v1/mcp/{your-tenant}Một trợ lý được cấp quyền như thế nào
Một trợ lý làm được những gì
Đúng những gì người đã kết nối nó làm được, quyết định theo từng lệnh gọi dựa trên chính token của họ. Một nhân viên tenant:support nhận được các công cụ chẩn đoán và công cụ hằng ngày; các công cụ quản trị không chỉ bị ẩn khỏi họ, mà còn bị từ chối nếu được gọi thẳng tên. Bất cứ thứ gì bị chặn bên trong cổng quản lý thì vẫn bị chặn: đổi địa chỉ email của một người dùng cần vai trò quản trị ở đó, và ở đây cũng cần.
Vì đây là một grant bình thường, bạn quản lý nó theo cách bình thường: gỡ trợ lý trên trang Ứng dụng đã cấp quyền trong tài khoản của bạn và nó không thể làm mới nữa, nên nó ngừng hoạt động khi access token hiện tại hết hạn. Mọi thay đổi mà một trợ lý thực hiện đều được ghi vào nhật ký kiểm toán của bạn dưới tên người mà nó thay mặt, nên dấu vết vẫn đúng là dấu vết bạn vẫn đọc lâu nay.
Các công cụ
Ba mươi ba công cụ trong bản phát hành này. Client AI của bạn quyết định bật những công cụ nào, nên bạn có thể chỉ giao cho một trợ lý các công cụ đọc, nếu đó là tất cả những gì bạn muốn nó làm.
| Công cụ | Vai trò | Công dụng |
|---|---|---|
find_user | Hỗ trợ | Tìm người dùng theo email, tiền tố tên hoặc id. Điểm khởi đầu cho mọi thứ còn lại. |
get_user | Hỗ trợ | Toàn bộ thông tin của một người dùng, gồm cả việc họ có đang hoạt động, đã xác nhận và có bị khóa hay không. |
get_user_mfa | Hỗ trợ | Người đó đã đăng ký những yếu tố thứ hai nào. |
get_user_sessions | Hỗ trợ | Người dùng hiện đang đăng nhập ở những đâu. |
search_audit | Hỗ trợ | Tìm trong nhật ký kiểm toán theo người thực hiện, hành động hoặc đối tượng bị tác động. |
list_users | Hỗ trợ | Liệt kê danh bạ, có thể lọc theo một tổ chức. |
get_user_stats | Hỗ trợ | Bạn có bao nhiêu người dùng và bao nhiêu người dùng yếu tố thứ hai. |
invite_user | Hỗ trợ | Mời ai đó qua email. |
resend_invite | Hỗ trợ | Gửi lại một lời mời. |
send_verification_email | Hỗ trợ | Gửi lại thư xác minh email. |
update_user | Hỗ trợ | Cập nhật một hồ sơ. Thay đổi địa chỉ email vẫn cần quyền quản trị. |
revoke_user_sessions | Hỗ trợ | Đăng xuất một người dùng ở mọi nơi. |
list_roles | Quản trị | Các vai trò được định nghĩa trong tenant của bạn. |
list_role_members | Quản trị | Ai đang giữ một vai trò nhất định. |
assign_role | Quản trị | Gán một vai trò cho người dùng. |
unassign_role | Quản trị | Gỡ một vai trò. |
reset_user_mfa | Quản trị | Xóa mọi yếu tố thứ hai, dành cho người đã mất ứng dụng xác thực. |
get_settings | Quản trị | Cấu hình tenant của bạn. |
list_sso_connections | Quản trị | Các kết nối SSO của bạn và những miền mà chúng bao phủ. |
list_organizations | Quản trị | Các tổ chức trong tenant của bạn, mỗi lần một trang. |
get_organization | Quản trị | Một tổ chức theo id hoặc slug, kèm các miền email của nó. |
create_organization | Quản trị | Tạo một tổ chức. Slug là vĩnh viễn. |
update_organization | Quản trị | Đổi tên, các tùy chọn chính sách, siêu dữ liệu hoặc thương hiệu của một tổ chức. Không thể đổi slug. |
delete_organization | Quản trị | Xóa một tổ chức cùng mọi tư cách thành viên của nó. |
list_organization_members | Quản trị | Các thành viên của một tổ chức, mỗi lần một trang. |
add_organization_member | Quản trị | Thêm một người dùng vào một tổ chức. |
update_organization_member | Quản trị | Đổi trạng thái hoặc vai trò của một thành viên trong một tổ chức. |
remove_organization_member | Quản trị | Gỡ một người dùng khỏi một tổ chức. |
add_organization_domain | Quản trị | Đăng ký quyền sở hữu một miền email cho một tổ chức. Trả về bản ghi DNS TXT cần công bố. |
verify_organization_domain | Quản trị | Kiểm tra bản ghi TXT và đánh dấu miền là đã xác minh. Có thể lặp lại an toàn. |
remove_organization_domain | Quản trị | Bỏ yêu cầu sở hữu một miền. Các thành viên hiện có vẫn ở lại. |
list_user_organizations | Quản trị | Các tổ chức mà một người dùng thuộc về, kèm trạng thái và vai trò trong từng tổ chức. |
list_clients | Nhà phát triển | Các client OAuth đã đăng ký trong tenant của bạn. |
Công cụ đọc và công cụ ghi đều được đánh dấu
Những gì chưa có
Xóa người dùng, tạo hoặc sửa kết nối SSO, thanh toán, sao lưu và client secret đều vắng mặt trong bản phát hành này. Việc xóa thuộc về hàng đợi xóa dữ liệu của bạn chứ không phải nằm cạnh nó; một kết nối SSO lớn tới mức một lần sửa sai sẽ khóa cả lực lượng lao động ở bên ngoài, nên hiện tại chúng chỉ đọc; và một công cụ trả về client secret sẽ đặt bí mật đó vào bản ghi hội thoại của trợ lý. Hãy cho chúng tôi biết bạn muốn những mục nào trong số đó và theo thứ tự nào.
Xác thực máy chủ MCP
Nếu bạn công khai một máy chủ Model Context Protocol, Authagonal có thể là máy chủ ủy quyền đứng sau nó. Một trợ lý AI kết nối, người đứng sau nó đăng nhập và cấp quyền truy cập, còn máy chủ của bạn nhận được một bearer token bình thường mà bạn xác thực như với mọi API khác.
Cách làm thay thế là dán một khóa API vào cấu hình của trợ lý, tức là một thông tin xác thực không có người dùng nào đứng sau, không có hạn dùng, không có bước đồng ý và không có cách nào thu hồi một trình kết nối mà không phải xoay khóa cho tất cả mọi người. Làm theo kiểu OAuth nghĩa là grant thuộc về một người có tên cụ thể, hiện rõ trong nhật ký kiểm toán của bạn, và có thể bị thu hồi từ cổng quản lý mà không phải động tới bất cứ thứ gì khác.
Kết nối diễn ra thế nào
Toàn bộ quá trình trao đổi được dẫn dắt bởi discovery, nên một client tuân thủ chuẩn không cần cấu hình gì ngoài URL máy chủ của bạn.
| Bước | Điều gì xảy ra |
|---|---|
| 1 | Trình kết nối gọi máy chủ MCP của bạn mà không có token và nhận về 401 chỉ ra nơi cần tìm. |
| 2 | Nó lấy metadata tài nguyên được bảo vệ của bạn, trong đó nêu tenant Authagonal của bạn là máy chủ ủy quyền. |
| 3 | Nó lấy metadata máy chủ ủy quyền của tenant và, vì chưa từng được đăng ký ở đâu, nó tự đăng ký. |
| 4 | Nó đưa người dùng tới đăng nhập và phê duyệt quyền truy cập, nêu máy chủ MCP của bạn là tài nguyên mà nó muốn xin token. |
| 5 | Nó gọi lại máy chủ của bạn bằng bearer token nhận được, token này chỉ giới hạn cho máy chủ của bạn và cho người dùng đó. |
Không có gì trong trình tự đó là riêng của Authagonal: đó là đặc tả ủy quyền của MCP, dựa trên RFC 9728 cho metadata tài nguyên, RFC 8414 để khám phá máy chủ ủy quyền, RFC 7591 để đăng ký và RFC 8707 để nêu tên tài nguyên. Một trình kết nối tuân theo đặc tả sẽ chạy được mà không cần xử lý riêng cho chúng tôi.
Cho phép trình kết nối tự đăng ký
Một trình kết nối mà bạn chưa từng gặp không thể dùng một client do bạn tạo bằng tay, nên nó đăng ký một client lúc chạy. Mặc định tính năng đó tắt. Hãy bật đăng ký client động trong Cài đặt và endpoint đăng ký sẽ xuất hiện trong tài liệu discovery của bạn; để tắt thì endpoint không được công bố và sẽ từ chối. Bật nó chỉ mở đăng ký cho riêng tenant của bạn, không bao giờ cho tenant của người khác.
| Rào chắn | Điều gì xảy ra |
|---|---|
| Loại cấp quyền | Chỉ có thể đăng ký luồng authorization code và luồng refresh. Việc tự đăng ký không thể tạo ra một client machine-to-machine bỏ qua hoàn toàn người dùng. |
| PKCE | Bắt buộc với mọi client đã đăng ký, bất kể yêu cầu đăng ký xin điều gì. |
| Sự đồng ý | Cũng bắt buộc. Một trình kết nối đã đăng ký không thể lấy được token cho tới khi có người xem những gì nó đang xin và phê duyệt. |
| Phạm vi | Các phạm vi sẵn có của OIDC luôn dùng được. Ngoài những phạm vi đó, một client tự đăng ký chỉ có thể xin một phạm vi tên là mcp, và chỉ khi tenant của bạn đã định nghĩa nó mà không có giới hạn vai trò. Không thể tự đăng ký roles và groups. |
| Giới hạn tần suất | Mười lần đăng ký cho mỗi địa chỉ IP mỗi giờ, nên một endpoint mở không thể bị dùng để làm đầy kho client của bạn. |
Cả hai đường dẫn discovery đều được phục vụ
/.well-known/oauth-authorization-server (RFC 8414), còn client OIDC dùng /.well-known/openid-configuration. Tenant của bạn trả lời trên cả hai đường dẫn với cùng metadata, nên một trình kết nối tuân theo đặc tả MCP tìm được bạn mà không cần ai chỉ chỗ.Máy chủ MCP của bạn cần triển khai gì
Hai việc nhỏ, sau đó nó chỉ là một resource server bình thường. Đầu tiên, hãy công bố metadata tài nguyên được bảo vệ nêu tenant của bạn là máy chủ ủy quyền. Phục vụ nó ở đường dẫn well-known và, nếu endpoint MCP của bạn nằm trên một đường dẫn con, phục vụ cả ở dạng có hậu tố đường dẫn, vì client thử cả hai.
GET https://your-app.example/.well-known/oauth-protected-resource
{
"resource": "https://your-app.example/mcp",
"authorization_servers": ["https://acme.authagonal.io"],
"bearer_methods_supported": ["header"],
"scopes_supported": ["mcp"]
}Thứ hai, khi một lệnh gọi đến mà không có token hợp lệ, hãy trả về 401 kèm header WWW-Authenticate trỏ tới metadata đó. Chính header đó biến một lần từ chối thành một kết nối: không có nó, client không có cách nào biết cần xác thực ở đâu, và đơn giản là thất bại.
// Validate the connector's token like any other resource server.
builder.Services.AddAuthentication().AddJwtBearer("McpBearer", o =>
{
o.Authority = "https://acme.authagonal.io"; // your tenant
o.TokenValidationParameters.ValidAudience = "https://your-app.example/mcp";
});
// Unauthenticated? Point the connector at the metadata rather than just refusing.
http.Response.Headers.WWWAuthenticate =
"Bearer resource_metadata=\"https://your-app.example/.well-known/oauth-protected-resource\"";
return Results.Unauthorized();Kiểm tra audience, không chỉ chữ ký
Phạm vi, gói dịch vụ và thu hồi
Hãy định nghĩa một phạm vi tên là mcp trên trang Phạm vi của bạn, không có giới hạn vai trò, và một trình kết nối tự đăng ký có thể yêu cầu nó; nó xuất hiện trên màn hình đồng ý để người dùng thấy họ đang phê duyệt điều gì. Chủ thể (subject) của token là người đã đăng nhập, nên máy chủ của bạn có thể quyết định chính người này được làm gì, thay vì đối xử với mọi trình kết nối như nhau. Một trình kết nối tự đăng ký không thể yêu cầu phạm vi roles hoặc groups, vì vậy hãy tra cứu chúng ở phía bạn thay vì trông chờ chúng có trong token.
Vì đây là một grant OAuth bình thường, việc thu hồi cũng diễn ra theo cách bình thường: người dùng gỡ trình kết nối trên trang Ứng dụng đã cấp quyền trong tài khoản của họ, thao tác này xóa grant và refresh token của nó nên nó không thể gia hạn. Các access token hiện có của nó bị /connect/introspect và /connect/userinfo từ chối ngay lập tức; một máy chủ chỉ xác thực JWT cục bộ vẫn chấp nhận token đó cho đến khi hết hạn. Nhật ký kiểm toán ghi lại mỗi lần đăng nhập cùng với client mà lần đăng nhập đó dành cho.
| Cài đặt | Điều gì xảy ra |
|---|---|
Dynamic client registration | Cài đặt trong cổng quản lý cho phép trình kết nối tự đăng ký. Mặc định tắt. |
mcp | Phạm vi duy nhất ngoài các phạm vi sẵn có của OIDC mà một client tự đăng ký có thể yêu cầu. Hãy định nghĩa nó trong tenant của bạn, không có giới hạn vai trò, để cung cấp nó. |
resource | Tham số mà trình kết nối gửi để nêu tên máy chủ MCP của bạn, thu hẹp audience của token về đúng nó. |
Xây dựng giao diện đăng nhập tùy chỉnh
Thay thế các màn hình đăng nhập, đăng ký, đặt lại mật khẩu và MFA được lưu trữ sẵn của Authagonal bằng giao diện của riêng bạn, trong khi Authagonal vẫn xử lý việc xác thực, MFA, SSO, phiên và cấp phát token. Có hai hướng: dùng thư viện component React của chúng tôi, hoặc gọi trực tiếp API xác thực từ bất kỳ framework nào. Đây là tính năng tùy chọn: hãy bật Giao diện đăng nhập tùy chỉnh tại Cài đặt → Phiên trước.


Điều kiện tiên quyết: một tên miền tùy chỉnh trên tên miền gốc của bạn
Phiên đăng nhập là cookie bên thứ nhất, vì vậy giao diện của bạn và máy chủ xác thực Authagonal phải dùng chung một tên miền đăng ký được. Trỏ một tên miền xác thực tùy chỉnh đến Authagonal trên cùng tên miền gốc mà ứng dụng của bạn chạy — ví dụ, xác thực tại login.acme.com, ứng dụng tại app.acme.com. Cài đặt Custom login UI vẫn bị tắt cho đến khi có một tên miền tùy chỉnh đang hoạt động.
| Giao diện của bạn | Máy chủ xác thực | Hoạt động? |
|---|---|---|
| app.acme.com | login.acme.com | ✅ cùng tên miền gốc |
| acme.com | auth.acme.com | ✅ cùng tên miền gốc |
| app.acme.com | acme.authagonal.io | ❌ khác site |
| myapp.io | login.acme.com | ❌ khác site |
Vì sao bắt buộc phải có tên miền tùy chỉnh
Không cần cài đặt CORS nào trên client cho các lời gọi /api/auth: khi Giao diện đăng nhập tùy chỉnh được bật, mọi origin trên cùng tên miền có thể đăng ký (registrable domain) với tên miền xác thực của bạn đều tự động được chấp nhận. Chỉ thêm origin của giao diện (ví dụ https://app.acme.com) vào CORS Origins được phép của client (Clients → URIs) nếu trình duyệt cũng thực hiện việc trao đổi token.
React: @authagonal/login
npm i @authagonal/login cung cấp logic xác thực và giao diện trong một gói duy nhất — chính gói mà trang đăng nhập được lưu trữ của Authagonal được xây dựng trên đó. Chọn mức độ phù hợp:
- Toàn bộ ứng dụng — đặt
Appvào và tạo giao diện qua thương hiệu. - Ghép các trang — dùng
LoginPage,MfaChallengePage,ResetPasswordPage… trong bố cục của riêng bạn. - Thành phần cơ bản + logic — tự xây các màn hình của riêng bạn với
AuthLayout/Button/Inputvà API client (login,mfaVerify,forgotPassword, …).
import { AuthLayout, Input, Button, login, ApiRequestError } from '@authagonal/login';
// returnUrl: the /connect/authorize URL your login page was opened with
function MyLogin({ returnUrl }: { returnUrl: string }) {
async function onSubmit(email: string, password: string) {
try {
const res = await login(email, password, returnUrl); // POST /api/auth/login (sets the session cookie)
if (res.mfaRequired) {/* render your MFA step, then mfaVerify(res.challengeId!, 'totp', code) */}
else if (res.mfaSetupRequired) {/* enrol first: mfaTotpSetup(res.setupToken) */}
else window.location.href = returnUrl; // resume /connect/authorize
} catch (e) {
if (e instanceof ApiRequestError) {/* show e.message; e.error is the error code */}
}
}
return <AuthLayout>{/* your own markup + <Input/> <Button/> */}</AuthLayout>;
}Mọi framework: gọi API xác thực
Không dùng React? Gọi trực tiếp các điểm cuối luồng xác thực (dưới /api/auth), rồi chuyển giao cho luồng OIDC chuẩn /connect/authorize. Gửi credentials: 'include' để cookie phiên được lưu lại.
| Điểm cuối | Mục đích |
|---|---|
POST /api/auth/login | Xác thực; trả về mfaRequired hoặc một URL chuyển hướng về |
POST /api/auth/register | Tự đăng ký (khi được bật) |
POST /api/auth/forgot-password | Bắt đầu đặt lại mật khẩu |
POST /api/auth/reset-password | Hoàn tất đặt lại mật khẩu |
GET /api/auth/password-policy | Chính sách mật khẩu (để hiển thị các quy tắc) |
POST /api/auth/mfa/* | Thiết lập + xác minh MFA (TOTP, WebAuthn, mã khôi phục) |
Dùng credentials: 'include'
# 1. Authenticate (browser fetch; credentials:'include' so the session cookie is stored)
curl -i -X POST https://login.acme.com/api/auth/login \
-H "Content-Type: application/json" \
-H "Origin: https://app.acme.com" \
--data '{"email":"[email protected]","password":"..."}'
# (handle {"mfaRequired":true} → POST /api/auth/mfa/verify, then continue)
# 2. Hand off to the OAuth flow: top-level navigation to the authorize endpoint with PKCE:
# https://login.acme.com/connect/authorize?client_id=my-app&redirect_uri=...&response_type=code
# &scope=openid%20profile%20email&code_challenge=...&code_challenge_method=S256
# The session cookie (same-site) authenticates the user; you get back a code → exchange at /connect/token.Một tenant, nhiều khách hàng
Một mẫu cho một nhà tích hợp, một tenant và N khách hàng mang thương hiệu riêng, mỗi khách hàng có tên miền đăng nhập và người dùng riêng, mà không cần một tenant cho mỗi khách hàng. Đây là điều mà cung cấp khai báo và tổ chức tồn tại để biến thành một thay đổi cấu hình thay vì một công việc kỹ thuật.
Mô hình
- Một tổ chức cho mỗi khách hàng, bên trong một tenant duy nhất.
- Một tên miền đăng nhập mang thương hiệu cho mỗi khách hàng, mỗi tên miền được ghim vào tổ chức của khách hàng đó, nên đăng nhập trên đó chỉ có thể tạo token cho tổ chức ấy.
- Ứng dụng cũng được phục vụ theo từng host khách hàng, tất cả từ cùng một lần triển khai: không có gì về mã, bản build hay image khác nhau giữa các khách hàng.
- Relying party chọn authority từ host mà nó đang chạy, không phải từ hằng số tại thời điểm build: cùng một bundle tự kết nối với một tên miền đăng nhập khác nhau tùy theo host khách hàng nào phục vụ nó.
Từng bước
Cung cấp khách hàng. Gọi endpoint cung cấp khai báo với một spec nêu tên tổ chức mới và tên miền của nó. Lệnh gọi này idempotent và có phạm vi theo từng phần.
{
"organizations": [
{ "slug": "acme", "name": "Acme Pty Ltd" }
],
"customDomains": [
{ "domain": "login.acme.example", "organizationSlug": "acme" }
]
}Trỏ DNS của khách hàng về tenant. Một CNAME từ zone riêng của khách hàng, chứng minh quyền kiểm soát và ý định, không cần token TXT.
_authagonal-challenge.login.acme.example. CNAME <slug>.<platformDomain>.
Cùng tài khoản Cloudflare với nền tảng?
Trỏ ứng dụng về host của khách hàng. Relying party tự phân giải OIDC authority của mình theo từng yêu cầu, dựa trên host mà nó đang phục vụ. Host không có mục trong bản đồ khách hàng sẽ quay về cách suy ra tenant đơn kiểu cổ điển, nên thêm một khách hàng thuần túy là phép cộng thêm.
export function resolveCustomer(): { authority: string; clientId: string } {
const cfg = getConfig();
const customer = cfg.customers?.[window.location.host];
if (customer) return customer;
const baseDomain = cfg.baseDomain || window.location.hostname.replace(/^consumer\./, '');
return { authority: `https://${cfg.tenantSlug}.${baseDomain}`, clientId: cfg.clientId };
}Client không yêu cầu gì riêng cho tổ chức: không có tham số organization, không có scope riêng cho từng khách hàng. Việc ghim tên miền thực hiện toàn bộ việc chọn tổ chức ở phía server, và đó là điều làm cho "ứng dụng là cùng một mã cho mọi khách hàng" thực sự đúng.
Khách hàng nhìn thấy gì
Trang đăng nhập hiển thị giao diện riêng của từng tổ chức được gộp lên giao diện của tenant. Xem Ghi đè giao diện. Mỗi khách hàng có thể có tên ứng dụng, logo, màu sắc và e-mail hỗ trợ riêng mà không ảnh hưởng đến các khách hàng khác.
Người dùng của khách hàng A cố đăng nhập trên host của khách hàng B sẽ bị từ chối, không được xem dữ liệu của khách hàng B, theo một trong hai dạng tùy cách xung đột phát sinh:
- Relying party không gửi gì và chỉ đến tên miền được ghim: bản ghim cung cấp tổ chức thay cho người dùng, việc chọn lúc này là rõ ràng, và người dùng khách hàng A không có tư cách thành viên trong B sẽ bị từ chối tại thời điểm token sẽ được tạo.
- Relying party tự nêu tên một tổ chức khác: bị middleware ghim tên miền từ chối trực tiếp với
400, trước khi bất kỳ trang đăng nhập nào được hiển thị.
Từ chối do thiếu tư cách thành viên chuyển hướng về ứng dụng
error=access_denied thông thường về redirect_uri của chính relying party, với phần mô tả nêu chính xác tư cách thành viên tổ chức nào còn thiếu.Tiếp nhận khách hàng thứ N+1
Khi Terraform điều khiển lệnh gọi cung cấp, tiếp nhận thêm một khách hàng chỉ là chỉnh sửa một tệp: thêm một mục vào mảng organizations, thêm một mục tên miền để ghim nó, thêm một bản ghi DNS. Không có gì về ứng dụng, việc triển khai hay bản build thay đổi: bộ phân giải theo host nhận khách hàng mới ngay khi mục cấu hình của họ tồn tại.
Triển khai tham chiếu
Một tenant dev lâu dài thực hiện toàn bộ mẫu này từ đầu đến cuối với hai tên miền khách hàng thật, cùng một bộ kiểm thử end-to-end cung cấp thành viên, kiểm tra giao diện và claim org_id, và khẳng định cả hai dạng từ chối ở trên. Đây là tài liệu có thể thực thi, không chỉ là mô tả.
cd e2e-consumer && DOMAIN=authagonal.dev npx playwright test organizations-domains
Bộ kiểm thử chạy mặc định như mọi spec khác; có thể bỏ qua trong môi trường chưa cung cấp các tên miền tham chiếu, vì đây là spec duy nhất trong bộ phụ thuộc vào hạ tầng nằm ngoài tầm kiểm soát của chính repo.
Gói & Giới hạn
Authagonal cung cấp gói Miễn phí và bốn cấp gói trả phí. Mọi gói đều bao gồm mọi tính năng xác thực. Các gói khác nhau ở giới hạn Người dùng Hoạt động Hàng tháng (MAU) và giá phần vượt quá, và gói Miễn phí chỉ có hỗ trợ từ cộng đồng, không có bộ phận hỗ trợ của tenant.
Cấp gói
| Gói | Giới hạn MAU | Phần vượt quá | Chi phí vượt quá/Người dùng |
|---|---|---|---|
| Miễn phí | 250 | Không | — |
| Starter | 1,000 | Không | — |
| Pro | 5.000 | Có | $0,04/người dùng |
| Scale | 25.000 | Có | $0,025/người dùng |
| Enterprise | 100.000 | Có | $0,015/người dùng |
Người dùng Hoạt động Hàng tháng (MAU)
Người dùng Hoạt động Hàng tháng là bất kỳ người dùng duy nhất nào xác thực thành công ít nhất một lần trong một tháng dương lịch (UTC). Người dùng được cung cấp qua SCIM nhưng chưa đăng nhập không được tính vào tổng MAU.
Phần vượt quá: nếu gói của bạn hỗ trợ phần vượt quá (Pro trở lên) và phần vượt quá được bật cho tenant của bạn (mặc định bị tắt), người dùng vượt giới hạn MAU sẽ được tính theo mức giá mỗi người dùng trong bảng gói ở trên. Giới hạn phần vượt quá đặt số người dùng bổ sung tối đa được phép vượt quá giới hạn.
Thực thi: nếu gói của bạn không hỗ trợ phần vượt quá (Miễn phí, Starter) hoặc phần vượt quá chưa được bật, người dùng đã đăng nhập trong tháng này luôn giữ được quyền truy cập. Khi tenant vượt giới hạn lần đầu, một thời gian ân hạn 10 ngày bắt đầu, trong đó người dùng mới vẫn có thể đăng nhập. Sau thời gian đó, người dùng chưa đăng nhập trong tháng này sẽ bị từ chối cho đến tháng sau hoặc cho đến khi bạn nâng cấp.
Đầy đủ tính năng trên mọi gói