Tôi nghĩ rằng bạn đang xác thực và ủy quyền .
Tôi hoàn toàn đồng ý rằng việc giữ mô hình bảo mật trong DB là khôn ngoan, đặc biệt là khi LedgerSMB được thiết kế với sự truy cập từ nhiều khách hàng. Trừ khi bạn có kế hoạch đi 3 tầng với lớp phần mềm trung gian, sẽ rất hợp lý khi có người dùng làm vai trò cơ sở dữ liệu, đặc biệt là đối với một ứng dụng kế toán.
Điều này không có nghĩa là bạn phải xác thực người dùng dựa trên cơ sở dữ liệu bằng phương thức xác thực được PostgreSQL hỗ trợ. Người dùng cơ sở dữ liệu, vai trò và trợ cấp của bạn chỉ có thể được sử dụng để ủy quyền nếu bạn muốn.
Đây là cách nó hoạt động cho một web ui chẳng hạn:
jane
kết nối với máy chủ web ui và xác thực bằng bất kỳ phương thức nào mong muốn, nói bắt tay chứng chỉ ứng dụng khách HTTPS X.509 và xác thực DIGEST. Máy chủ hiện có kết nối từ người dùng mà nó chấp nhận là thực sự jane
.
Máy chủ kết nối với PostgreSQL bằng tên người dùng / mật khẩu cố định (hoặc Kerberos hoặc bất cứ thứ gì bạn thích), xác thực chính nó với máy chủ db là người dùng webui
. Máy chủ db tin tưởng webui
để xác thực người dùng của nó vì vậy webui
đã được cung cấp GRANT
s thích hợp (xem bên dưới).
Trên kết nối đó, máy chủ sử dụng SET ROLE jane;
để đảm nhận mức ủy quyền của người dùng jane
. Cho đến khi RESET ROLE;
hoặc một cái khác SET ROLE
được chạy, kết nối đang hoạt động với quyền truy cập tương tự jane
và SELECT current_user()
vv sẽ báo cáo jane
.
Các máy chủ duy trì các mối liên hệ giữa các kết nối cơ sở dữ liệu mà nó có SET ROLE
tới jane
và phiên web cho người sử dụng jane
, không cho phép kết nối PostgreSQL được sử dụng bởi các kết nối khác với những người dùng khác mà không có một mới SET ROLE
Inbetween.
Bạn đang chứng thực bên ngoài máy chủ, nhưng việc duy trì quyền trong máy chủ. PG cần biết những gì người dùng tồn tại, nhưng không cần mật khẩu hoặc phương thức xác thực cho họ.
Xem:
Chi tiết
Máy chủ webui kiểm soát các truy vấn chạy và nó sẽ không jane
chạy SQL thô (tôi hy vọng!) Vì vậy jane
không thể RESET ROLE; SET ROLE special_admin_user;
thông qua web ui. Để an toàn hơn, tôi thêm bộ lọc câu lệnh vào máy chủ đã từ chối SET ROLE
và RESET ROLE
trừ khi kết nối nằm trong hoặc nhập vào nhóm kết nối chưa được gán.
Bạn vẫn được tự do sử dụng xác thực trực tiếp để PG trong các máy khách khác; bạn có thể trộn và kết hợp tự do. Bạn chỉ cần GRANT
những webui
người sử dụng quyền SET ROLE
để người dùng có thể đăng nhập qua web và sau đó cung cấp cho những người dùng bất kỳ bình thường CONNECT
quyền, mật khẩu, vv mà bạn muốn. Nếu bạn muốn đặt chúng chỉ trên web, quyền REVOKE
của chúng CONNECT
trên cơ sở dữ liệu (và từ public
).
Để làm cho việc phân tách xác thực / ủy quyền dễ dàng như vậy, tôi có một vai trò đặc biệt assume_any_user
mà GRANT
mọi người dùng mới được tạo. Sau đó, tôi GRANT assume_any_user
đến tên người dùng thực sự được sử dụng bởi những thứ như giao diện web đáng tin cậy, cho họ quyền trở thành bất kỳ người dùng nào họ thích.
Điều quan trọng là phải đảm assume_any_user
một NOINHERIT
vai trò, vì vậy webui
người sử dụng hay bất cứ điều gì không có privilges bởi tự nó và chỉ có thể hoạt động trên cơ sở dữ liệu khi nó đã SET ROLE
cho một người dùng thực sự. Trong mọi trường hợp nên webui
là một siêu người dùng hoặc chủ sở hữu DB .
Nếu bạn kết nối nhóm, bạn chỉ có thể sử dụng SET LOCAL ROLE
để đặt vai trò trong một giao dịch, do đó bạn có thể trả lại kết nối cho nhóm sau COMMIT
hoặc ROLLBACK
. Coi chừng RESET ROLE
vẫn hoạt động, vì vậy vẫn không an toàn khi để máy khách chạy bất kỳ SQL nào họ muốn.
SET SESSION AUTHORIZATION
là phiên bản liên quan nhưng mạnh hơn của lệnh này. Nó không yêu cầu thành viên vai trò, nhưng đó là một lệnh siêu người dùng. Bạn không muốn web của bạn kết nối như một siêu người dùng. Nó có thể được đảo ngược với RESET SESSION AUTHORIZATION
, SET SESSION AUTHORIZATION DEFAULT
hoặc SET SESSION AUTHORIZATION theusername
để lấy lại quyền superuser nên nó không phải là một rào cản an ninh đặc quyền-thả một trong hai.
Một lệnh hoạt động như thế SET SESSION AUTHORIZATION
nhưng không thể đảo ngược và sẽ hoạt động nếu bạn là thành viên vai trò nhưng không phải siêu người dùng sẽ rất tuyệt. Tại thời điểm này không có, nhưng bạn vẫn có thể tách biệt xác thực và ủy quyền khá tốt nếu bạn cẩn thận.
Ví dụ và giải thích
CREATE ROLE dbowner NOLOGIN;
CREATE TABLE test_table(x text);
INSERT INTO test_table(x) VALUES ('bork');
ALTER TABLE test_table OWNER TO dbowner;
CREATE ROLE assume_any_user NOINHERIT NOLOGIN;
CREATE ROLE webui LOGIN PASSWORD 'somepw' IN ROLE assume_any_user;
CREATE ROLE jane LOGIN PASSWORD 'somepw';
GRANT jane TO assume_any_user;
GRANT ALL ON TABLE test_table TO jane;
CREATE ROLE jim LOGIN PASSWORD 'somepw';
GRANT jim TO assume_any_user;
Bây giờ kết nối như webui
. Lưu ý rằng bạn không thể làm bất cứ điều gì để test_table
mà bạn có thể SET ROLE
đến jane
và sau đó bạn có thể truy cập vào test_table
:
$ psql -h 127.0.0.1 -U webui regress
Password for user webui:
regress=> SELECT session_user, current_user;
session_user | current_user
--------------+--------------
webui | webui
(1 row)
regress=> SELECT * FROM test_table;
ERROR: permission denied for relation test_table
regress=> SET ROLE jane;
SET
regress=> SELECT session_user, current_user;
session_user | current_user
--------------+--------------
webui | jane
(1 row)
regress=> SELECT * FROM test_table;
x
------
bork
(1 row)
Lưu ý rằng webui
can SET ROLE
tới jim
, ngay cả khi đã SET ROLE
d đến jane
và mặc dù jane
chưa được GRANT
ed quyền giả định vai trò jim
. SET ROLE
đặt ID người dùng hiệu quả của bạn, nhưng nó không loại bỏ khả năng của bạn đối SET ROLE
với các vai trò khác, đó là một thuộc tính của vai trò bạn đã kết nối chứ không phải vai trò hiệu quả hiện tại của bạn. Do đó, bạn phải kiểm soát cẩn thận quyền truy cập vào các lệnh SET ROLE
và RESET ROLE
. AFAIK, không có cách nào để SET ROLE
kết nối vĩnh viễn , thực sự trở thành người dùng mục tiêu, mặc dù điều đó chắc chắn sẽ rất tốt nếu có.
Đối chiếu:
$ psql -h 127.0.0.1 -U webui regress
Password for user webui:
regress=> SET ROLE jane;
SET
regress=> SET ROLE jim;
SET
regress=> SELECT session_user, current_user;
session_user | current_user
--------------+--------------
webui | jim
(1 row)
đến:
$ psql -h 127.0.0.1 -U jane regress
Password for user jane:
regress=> SET ROLE webui;
ERROR: permission denied to set role "webui"
regress=> SET ROLE jim;
ERROR: permission denied to set role "jim"
Điều này có nghĩa SET ROLE
là không chính xác giống như đăng nhập như một vai trò nhất định, một điều bạn phải ghi nhớ.
webui
Không SET ROLE
thể dbowner
vì nó đã không GRANT
đúng:
regress=> SET ROLE dbowner;
ERROR: permission denied to set role "dbowner"
do đó, bản thân nó khá bất lực, nó chỉ có thể đảm nhận quyền của những người dùng khác và chỉ khi những người dùng đó có quyền truy cập web.