LỖI: quyền bị từ chối đối với tên bảng quan hệ trên Postgres trong khi thử SELECT với tư cách người dùng chỉ đọc


89
GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly;

Người dùng chỉ đọc có thể kết nối, xem các bảng nhưng khi cố gắng thực hiện một lựa chọn đơn giản, nó sẽ nhận được:

ERROR: permission denied for relation mytable
SQL state: 42501

Điều này đang xảy ra trên PostgreSQL 9.1

Tôi đã làm sai điều gì?


1
Bạn có thể cung cấp một số chi tiết về "quan hệ bàn của tôi"? Schema, nó là một "thực" bảng (hoặc một cái nhìn / chức năng), gây nên ...
Igor Romanchenko

Câu trả lời:


162

Đây là giải pháp hoàn chỉnh cho PostgreSQL 9+, được cập nhật gần đây.

CREATE USER readonly  WITH ENCRYPTED PASSWORD 'readonly';
GRANT USAGE ON SCHEMA public to readonly;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO readonly;

-- repeat code below for each database:

GRANT CONNECT ON DATABASE foo to readonly;
\c foo
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO readonly; --- this grants privileges on new tables generated in new database "foo"
GRANT USAGE ON SCHEMA public to readonly; 
GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly;

Cảm ơn https://jamie.curle.io/creating-a-read-only-user-in-postgres/ về một số khía cạnh quan trọng

Nếu bất kỳ ai tìm thấy mã ngắn hơn và tốt nhất là mã có thể thực hiện điều này cho tất cả các cơ sở dữ liệu hiện có, thì sẽ có thêm kudo.


6
cái này có bao gồm lượt xem không?
Frank Conry

9
Tại sao bạn cấp GRANT ALLquyền theo mặc định cho người dùng chỉ đọc?
Slava Fomin II

1
tôi đã cung cấp chính xác như nó được xác định, vẫn còn lỗi sam
Anish Gopinath

có thể xác nhận quyền được cấp bằng cách sử dụng \ddp. Nên hiển thị =r/giống như granting_user=r/readonly_usercho quyền truy cập chỉ đọc.
Greg Bray

Đây là SQL nguyên văn từ câu hỏi. Tôi không thấy nó cung cấp một giải pháp như thế nào.
r351574nc3

12

Cố gắng thêm

GRANT USAGE ON SCHEMA public to readonly;

Có thể bạn đã không biết rằng một người cần có các quyền cần thiết đối với một lược đồ, để sử dụng các đối tượng trong lược đồ.


Có điều gì đó kỳ lạ đang xảy ra, tôi chạy các lệnh này trên máy chủ psqlvới tư cách là postgresngười dùng và tôi nhận được phản hồi thích hợp , GRANT. Tuy nhiên, khi tôi nhìn vào ACL trên các bảng, tôi chỉ thấy hai tài khoản khác, một tài khoản là chủ sở hữu cơ sở dữ liệu jirauservà một tài khoản chỉ đọc khác có tên qauser. Nhưng của tôi readonlykhông xuất hiện ở đó. Postgres là phiên bản 9.1 và tôi thậm chí đã khởi động lại máy chủ, vẫn không có gì xảy ra.
sorin

2
đầu ra của \ du trong bảng điều khiển psql là gì? Bạn vẫn có thể cung cấp đầu ra này hoặc nó đã được sửa như trong câu trả lời của bạn?
sufleR

Tôi thực sự không biết điều gì đã xảy ra, vì đầu ra là chính xác (GRANT). YEsterday nó không hoạt động, nhưng hôm nay nó hoạt động sau khi chạy, một lần nữa, cả 3 lệnh.
sorin

3
Lưu ý: Thời gian đáp ứng dự kiến ​​cho điều này chỉ đơn giản là 'GRANT'. Nếu bạn thấy 'CẢNH BÁO: không có đặc quyền nào được cấp cho "công khai"' thì nó KHÔNG hoạt động. Người dùng chỉ đọc không thể cấp thêm quyền cho chính họ. Chỉ người dùng có quyền 'GRANT' mới có thể làm điều đó, vì vậy bạn có thể cần đăng nhập với tư cách là người dùng cấp cao.
PeterVermont

Xin chào, khi tôi cố gắng CẤP CHỌN TRÊN TẤT CẢ CÁC BẢNG TRONG SCHEMA ở chế độ công khai CHO người đăng bài; nó phản hồi: ERROR: quyền bị từ chối đối với khóa dữ liệu quan hệ. Bạn có biết tôi đang làm gì sai không? Cảm ơn (nó xảy ra trên GAppEngine Posgres9.6 bằng cách sử dụng địa chỉ công cộng và truy cập thông qua thiết bị đầu cuối)
Mike

-5

Điều này đã làm việc cho tôi:

Kiểm tra vai trò hiện tại mà bạn đã đăng nhập bằng cách sử dụng: SELECT CURRENT_USER, SESSION_USER;

Lưu ý : Nó phải khớp với Chủ sở hữu của lược đồ.

Lược đồ | Tên | Loại | Chủ đầu tư
-------- + -------- + ------- + ----------

Nếu chủ sở hữu khác, thì hãy cấp tất cả các quyền cho vai trò người dùng hiện tại từ vai trò quản trị viên bằng cách:

CẤP 'ROLE_OWNER' thành 'CURRENT ROLENAME';

Sau đó, hãy thử thực hiện truy vấn, nó sẽ đưa ra kết quả vì nó có quyền truy cập vào tất cả các quan hệ bây giờ.


5
Thay đổi chủ sở hữu thành một người dùng được gọi là readonly hầu như không phải là cách khắc phục phù hợp.
Anna

Tùy thuộc vào trường hợp của bạn, chủ sở hữu bàn sai thực sự có thể là nguyên nhân (đó là kẻ thù của tôi). Cách thích hợp để thay đổi bảng ownershiip trong PostgreSQL: xem stackoverflow.com/a/13535184
tanius

-6

đảm bảo rằng người dùng của bạn có các thuộc tính về vai trò của nó. ví dụ:

postgres=# \du
                             List of roles
 Role name |                   Attributes                   | Member of 
-----------+------------------------------------------------+-----------
 flux      |                                                | {}
 postgres  | Superuser, Create role, Create DB, Replication | {}

sau khi thực hiện lệnh sau:

postgres=# ALTER ROLE flux WITH Superuser;
ALTER ROLE
postgres=# \du
                             List of roles
 Role name |                   Attributes                   | Member of 
-----------+------------------------------------------------+-----------
 flux      | Superuser                                      | {}
postgres  | Superuser, Create role, Create DB, Replication | {}

nó đã khắc phục sự cố.

xem hướng dẫn về vai trò và nội dung tại đây: https://www.digitalocean.com/community/tutorials/how-to-use-roles-and-manage-grant-permissions-in-postgresql-on-a-vps--2


18
Không! Trao vai trò Superuser cho người dùng được gọi là "chỉ đọc" để thực hiện "lựa chọn" không phải là cách khắc phục chính xác.
Anna

@Anna Đó không phải là những gì đang xảy ra ở đây. Chủ đề này không phải là cấp quyền truy cập chỉ đọc. Chủ đề này nói về việc cấp cho người dùng quyền truy cập để cấp cho người dùng khác quyền truy cập chỉ đọc. IMHO, điều này là chính xác. Nếu người dùng của bạn không phải là Superuser, bạn không thể tạo người dùng chỉ đọc. Lỗi đang gặp phải là không thể tạo người dùng chỉ đọcERROR: permission denied for relation mytable
r351574nc3

-7

Bạn nên thực hiện truy vấn tiếp theo:

GRANT ALL ON TABLE mytable TO myuser;

Hoặc nếu lỗi của bạn là trong một dạng xem thì có thể bảng không có quyền, vì vậy bạn nên thực hiện truy vấn tiếp theo:

GRANT ALL ON TABLE tbm_grupo TO myuser;

5
Người dùng được gọi là "chỉ đọc". Có thể nghi ngờ rằng việc cung cấp cho người dùng tất cả các quyền là mục tiêu. Anh ấy chỉ muốn thực hiện một lựa chọn.
Anna

Điều này đánh bại mục đích đặt tên người dùng là 'ReadOnly' nếu bạn đang cung cấp ALTER DROP DELETEEct. Để người dùng mà ...
JayRizzo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.