Bỏ qua, đến nội dung

Câu hỏi thường gặp — Password Policy

Cấu hình

Chính sách có áp dụng cho user hiện tại không?

Không ngay lập tức. Chính sách chỉ kiểm tra khi user đổi mật khẩu hoặc tạo tài khoản mới. Mật khẩu hiện tại vẫn hoạt động bình thường cho đến lần đổi tiếp theo.

Tuy nhiên, nếu bật validityPeriod (hết hạn mật khẩu), tất cả user sẽ bị bắt đổi mật khẩu khi hết thời hạn — kể cả những user chưa bao giờ đổi mật khẩu kể từ khi cài plugin.

Cấu hình historyCount bao nhiêu là đủ?

Khuyến nghị 5–10. Điều này ngăn user quay vòng giữa các mật khẩu cũ. Plugin lưu tối đa 24 bản ghi lịch sử per user (hard limit), nên không nên đặt historyCount > 24.

Nên chọn mức complexity nào?

MứcPhù hợp choVí dụ mật khẩu hợp lệ
noneHệ thống nội bộ, ít nhạy cảmabcdef
alpha_numericHệ thống thông thườngabc123
numbers_upper_lowerHệ thống doanh nghiệpAbc123
numbers_upper_lower_specialHệ thống tài chính, bảo mật caoAbc123!@
3_of_4Linh hoạt — đạt 3/4 loại ký tựAbc123 hoặc abc!@#

Mức 3_of_4 hoạt động thế nào?

User phải đạt ít nhất 3 trong 4 loại ký tự:

  1. Chữ thường (a-z)
  2. Chữ hoa (A-Z)
  3. Chữ số (0-9)
  4. Ký tự đặc biệt (!@#$%^&*...)

Ví dụ: Abc123 (có chữ thường + chữ hoa + số = 3/4) ✅

Sử dụng

User báo không thể đổi mật khẩu?

Kiểm tra lần lượt:

  1. Mật khẩu mới không đạt yêu cầu complexity — xem thông báo lỗi cụ thể
  2. Trùng mật khẩu cũ — nếu bật historyCount, mật khẩu mới không được trùng N mật khẩu gần nhất
  3. Mật khẩu chứa username — nếu bật cantIncludeUsername
  4. Độ dài không hợp lệ — phải từ minLength đến 64 ký tự

Mật khẩu hết hạn, user bị khóa?

Khi mật khẩu hết hạn (validityPeriod), server trả về lỗi 401 "Password expired" khi đăng nhập. User cần liên hệ admin để reset mật khẩu.

Admin có thể reset mật khẩu cho user trong Settings → Users.

Tài khoản bị khóa do đăng nhập sai, phải làm gì?

Nếu lockoutDuration > 0:

  • Tài khoản tự động mở khóa sau lockoutDuration giây
  • Admin có thể mở khóa sớm trong Settings → Locked Users

Nếu lockoutDuration = 0:

  • Tài khoản không bị khóa thực sự, chỉ báo lỗi
  • Counter tự reset sau maxSignInAttemptsInterval giây

Làm sao biết mật khẩu sắp hết hạn?

Khi mật khẩu còn ≤ 10 ngày trước hết hạn, hệ thống gửi thông báo in-app mỗi lần đăng nhập. Thông báo qua kênh password-expiration-in-app-message (cấu hình trong expirationNotificationChannel).

Kỹ thuật

Mật khẩu cũ lưu ở đâu?

Lịch sử mật khẩu lưu trong bảng userPasswordHistory dưới dạng hash (giống cách lưu password trong bảng users). Không thể giải mã ngược.

TrườngKiểuMô tả
userIdbigIntID user
passwordstringPassword hash
createdTsunixTimestampThời điểm đổi mật khẩu (ms)

BloomFilter dùng để làm gì?

Plugin dùng BloomFilter để kiểm tra nhanh user có bị khóa hay không trước khi truy vấn database. BloomFilter có đặc tính:

  • Không bao giờ false negative: Nếu nó nói "không bị khóa" thì chắc chắn không bị khóa
  • Có thể false positive: Nếu nó nói "có thể bị khóa" thì cần kiểm tra thêm trong DB

Điều này giúp giảm tải database đáng kể khi hệ thống có nhiều request đăng nhập.

Plugin có ảnh hưởng hiệu năng đăng nhập không?

  • Kiểm tra lockout: Rất nhanh nhờ BloomFilter (O(1))
  • Đếm lần sai: Nhanh nhờ Counter cache
  • Kiểm tra hết hạn: 1 truy vấn DB (lấy bản ghi userPasswordHistory mới nhất)
  • Kiểm tra policy: Cache trong memory, không truy vấn DB mỗi lần

Tổng thể, overhead thêm vào mỗi lần đăng nhập là rất nhỏ (< 5ms trong điều kiện bình thường).

Tại sao publicList chỉ trả về một số tham số?

Endpoint publicList chỉ trả về minLength, cantIncludeUsername, và complexity — đủ để client-side validation hiển thị yêu cầu mật khẩu cho user. Các tham số bảo mật (maxSignInAttempts, lockoutDuration, v.v.) không được expose để tránh kẻ tấn công biết được giới hạn hệ thống.