BŁĄD: odmowa pozwolenia na relacyjną nazwę tabeli na Postgres podczas próby SELECT jako użytkownik tylko do odczytu

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

Użytkownik tylko do odczytu może się połączyć, zobaczyć tabele, ale kiedy próbuje wykonać prosty wybór, otrzymuje:

ERROR: permission denied for relation mytable
SQL state: 42501

Dzieje się tak w PostgreSQL 9.1

Co zrobiłem źle?

sorin
źródło
1
Czy możesz podać szczegóły dotyczące „mytych relacji”? Schemat, czy to "prawdziwy" stół (czy widok / funkcja), uruchamia ...
Igor Romanchenko

Odpowiedzi:

162

Oto kompletne rozwiązanie dla PostgreSQL 9+, zaktualizowane niedawno.

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;

Podziękowania dla https://jamie.curle.io/creating-a-read-only-user-in-postgres/ za kilka ważnych aspektów

Jeśli ktoś znajdzie krótszy kod, a najlepiej taki, który jest w stanie wykonać to dla wszystkich istniejących baz danych, dodatkowe gratyfikacje.

sorin
źródło
6
czy obejmuje to wyświetlenia?
Frank Conry,
9
Dlaczego GRANT ALLdomyślnie dajesz to uprawnienie użytkownikowi tylko do odczytu?
Slava Fomin II
1
podałem dokładnie tak, jak jest zdefiniowane, nadal sam błąd
Anish Gopinath
może potwierdzić prawa przyznane za pomocą \ddp. Powinien =r/wyglądać tak samo, jak w granting_user=r/readonly_userprzypadku dostępu tylko do odczytu.
Greg Bray
To jest dosłownie SQL z pytania. Nie widzę rozwiązania.
r351574nc3
12

Spróbuj dodać

GRANT USAGE ON SCHEMA public to readonly;

Prawdopodobnie nie byłeś świadomy, że trzeba mieć wymagane uprawnienia do schematu, aby używać obiektów w schemacie.

sufleR
źródło
Coś dziwnego się dzieje, że te komendy na serwerze używając psqljako postgresużytkownik i zrobić uzyskać właściwą odpowiedź, GRANT. Mimo to, gdy patrzę na listę ACL w tabelach, widzę tylko dwa inne konta, jedno będące właścicielem bazy danych, jirausera drugie o nazwie tylko do odczytu qauser. Ale mojego tam readonlynie ma. Postgres to wersja 9.1 i nawet zrestartowałem serwer, nadal nic się nie dzieje.
sorin
2
co jest / było wyjście \ du w konsoli psql? Czy nadal możesz podać to wyjście, czy jest już naprawione, jak w Twojej odpowiedzi?
sufleR
Naprawdę nie wiem, co się stało, ponieważ wynik był poprawny (GRANT). Wczoraj nie działało, ale dzisiaj działało po uruchomieniu ponownie wszystkich 3 poleceń.
sorin
3
Uwaga: oczekiwana odpowiedź to po prostu „GRANT”. Jeśli widzisz komunikat „OSTRZEŻENIE: nie przyznano żadnych uprawnień dla„ publicznego ””, to NIE zadziałało. Użytkownik tylko do odczytu nie może przyznać sobie dodatkowych uprawnień. Tylko użytkownik z uprawnieniami „GRANT” może to zrobić, więc prawdopodobnie musisz zalogować się jako superużytkownik.
PeterVermont,
Cześć, kiedy próbuję UDZIELAĆ WYBORU NA WSZYSTKICH TABLACH W SCHEMACIE public TO postgres; odpowiada: BŁĄD: odmowa pozwolenia dla bazy danych relacji blokada dziennika. Czy wiesz, co robię źle? Dzięki (dzieje się to na GAppEngine Posgres9.6 przy użyciu adresu publicznego i dostępie przez terminal)
Mike
-5

To zadziałało dla mnie:

Sprawdź bieżącą rolę, do której jesteś zalogowany, używając: SELECT CURRENT_USER, SESSION_USER;

Uwaga : musi pasować do właściciela schematu.

Schemat | Imię | Wpisz | Właściciel
-------- + -------- + ------- + ----------

Jeśli właściciel jest inny, przekaż wszystkie uprawnienia bieżącej roli użytkownika z roli administratora poprzez:

GRANT „ROLE_OWNER” dla „CURRENT ROLENAME”;

Następnie spróbuj wykonać zapytanie, da wynik, ponieważ ma teraz dostęp do wszystkich relacji.

Dhwani Shah
źródło
5
Zmiana właściciela na użytkownika o nazwie readonly nie brzmi jak właściwa poprawka.
Anna
W zależności od twojego przypadku przyczyną może być rzeczywiście zły właściciel stołu (był to wróg). Właściwy sposób na zmianę właściciela tabeli w PostgreSQL: zobacz stackoverflow.com/a/13535184
tanius
-6

upewnij się, że użytkownik ma atrybuty przypisane do swojej roli. na przykład:

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

po wykonaniu polecenia:

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 | {}

rozwiązało problem.

zobacz samouczek dotyczący ról i innych rzeczy tutaj: https://www.digitalocean.com/community/tutorials/how-to-use-roles-and-manage-grant-permissions-in-postgresql-on-a-vps--2

PuN1sh3r
źródło
18
Nie! Nadanie roli superużytkownika użytkownikowi o nazwie „tylko do odczytu” w celu dokonania „wyboru” nie jest poprawnym rozwiązaniem.
Anna
@Anna To nie to, co się tutaj dzieje. W tym wątku nie chodzi o udzielanie dostępu tylko do odczytu. W tym wątku chodzi o przyznanie użytkownikowi dostępu w celu nadania innemu użytkownikowi dostępu tylko do odczytu. IMHO, to jest poprawne. Jeśli Twój użytkownik nie jest superużytkownikiem, nie możesz utworzyć użytkownika tylko do odczytu. ERROR: permission denied for relation mytable
Wystąpił
-7

Powinieneś wykonać następne zapytanie:

GRANT ALL ON TABLE mytable TO myuser;

Lub jeśli twój błąd jest w widoku, być może tabela nie ma uprawnień, więc powinieneś wykonać następne zapytanie:

GRANT ALL ON TABLE tbm_grupo TO myuser;
tak
źródło
5
Użytkownik jest nazywany „tylko do odczytu”. Wątpliwe jest, aby celem było nadanie użytkownikowi wszystkich uprawnień. Chce tylko dokonać wyboru.
Anna
To mija się z celem nazwania użytkownika „ ALTER DROP DELETETylko do odczytu”, jeśli dajesz Ect. Do tego użytkownika ...
JayRizzo