2014-10-30 72 views
1

我有一個Web應用程序的Postgresql數據庫。數據庫由系統上的特定用戶擁有,比如說foouser。作爲所有者,此用戶對數據庫擁有完全權限。自動允許從用戶訪問postgres中的表格

服務器還有另一個用戶,比如webappuser,它是運行應用程序服務器的用戶。我不想在Web應用程序的配置文件中指定用戶名和密碼,而是使用「對等」身份驗證。我已經得到認證正常工作,但我遇到了以下問題。

當我創建PostgreSQL中webappuser角色,我又給了LOGIN許可以及GRANT ALL ON DATABASE foo TO webappuser;和數據庫GRANT ALL ON SCHEMA public TO webappuser;內。

我遇到的問題是與表權限。與MySQL允許所有表訪問數據庫的默認情況不同(在我看來,這是一個合理的假設),Postgresql拒絕訪問所有的表,即使已經在模式和數據庫上提供了權限。爲了解決這個問題,我必須明確地授予我使用GRANT ALL ON TABLE table_name TO webappuser;創建的所有新表,視圖,過程等的權限(以及類似的視圖等)。

結果是,每當我運行數據庫遷移時,我都必須爲創建的新表添加對數據庫的權限。問題是我無法將這個權限信息添加到遷移本身,因爲開發人員機器沒有這個額外的用戶。無論如何,這看起來確實是做錯事情的錯誤方式。

我怎樣才能允許從這個額外的用戶訪問數據庫表,而無需每次創建表,視圖,過程等時手動干預?

獎勵積分:有沒有辦法將用戶的權限限制爲僅限CRUD操作而不是完全權限,並且仍然自動完成整個任務?

+0

怎麼做你做「數據庫遷移」?這是運行DDL腳本還是你pg_dump/pg_restore? – Patrick 2014-10-30 05:34:33

+0

一般來說,不要授予'ALL',而是授予CRUD功能的特定特權,例如'GRANT SELECT,INSERT,UPDATE,DELETE'。 – Patrick 2014-10-30 05:37:20

+0

@Patrick我正在使用[Laravel的內置遷移](http://laravel.com/docs/4.2/migrations)創建SQL語句。這非常類似於Rails遷移,如果有幫助的話。 – 2014-10-30 05:37:29

回答

3

沒有關於Laravel遷移細節的經驗:當您在同一臺服務器上進行遷移時,只要遷移權限,也應該沒有問題,因爲webappuser在羣集範圍內可用。

當遷移到不同的服務器時,您需要在該新服務器上創建用戶並設置所有遷移對象的權限。你基本上有兩種方法來做到這一點。

首先是在遷移之前在模式表中設置默認特權,或者在遷移之後設置GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA sch_name TO webappuser。默認權限設置有:

ALTER DEFAULT PRIVILEGES IN SCHEMA sch_name 
    GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO webappuser; 

兩個指令均是完全SQL標準兼容,所以你應該有跨兼容的架構沒有問題。

請記住,在同一模式中創建的任何其他表也將具有設置爲webappuser的權限。由於潛在的權限泄漏,不建議在生產環境中爲「不可信」用戶(使用Web應用程序的用戶)設置權限;在開發環境中它可能是可以接受的。

第二個 - 我個人比較喜歡 - 寫一個存儲過程來設置適當的權限。做一次遷移,運行一次存儲過程,然後開始運行。這使您可以更多地控制權限授予。該過程可能類似於:

CREATE FUNCTION grant_webapp_privileges() RETURNS void AS $$ 
    -- Create the webappuser, if necessary 
    CREATE ROLE webappuser LOGIN; 

    -- Grant privileges on all required objects 
    GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE table1 TO webappuser; 
    ... 
$$ LANGUAGE SQL; 

在master數據庫上,只需在創建或刪除新關係時保持存儲過程爲最新。如果Laravel支持插入不在要遷移的模式中的代碼塊,則可以將上述過程設置爲在遷移後執行的匿名代碼塊。

(順便說一句,我從來沒有放棄webappuser樣角色CRUD訪問相反,我始終通過該隱藏一些底層的數據模型的細節,諸如person具有addresscontact_information和其他細節視圖提供訪問;所述這樣你就可以輕鬆地改變底層的關係並更新視圖,而不必調整你的web應用程序,與OOP相同的原則,更容易管理的權限)

+0

遷移旨在將數據庫結構更改作爲應用程序代碼放入源代碼存儲庫。這樣,應用程序的所有實例都將具有正確的數據庫結構。因此,必須設計遷移,使其在所有服務器上完全相同,而無需事先知道服務器的外觀。遷移跑步者唯一知道的是它有權連接到特定的數據庫。這就是爲什麼我不能在遷移之後運行特定於服務器的過程 - 因爲它也必須能夠在開發人員的個人計算機上運行。 – 2014-10-30 06:05:34

+0

因爲我總是可以依靠現有的模式(因爲遷移需要它已經預先創建),我想我將不得不使用您的「設置默認權限」選項。可以肯定的是,你是指使用['ALTER DEFAULT PRIVILEGES'](http://www.postgresql.org/docs/9.3/static/sql-alterdefaultprivileges.html)?你能用一個這樣的例子來擴展你的答案嗎? – 2014-10-30 06:07:26

+0

關於你的問題:在這種情況下,我選擇公開表,因爲表結構完全匹配應用程序結構 - 事實上,這個特定的應用程序完全是數據庫周圍的瘦REST API。還有第二個應用程序只能從可以使用只讀視圖的數據庫中進行選擇,但這不是這個問題的主題。無論如何,我不確定如何使用視圖對多對多關係進行建模,以便使它們同時易於查詢和輕鬆編輯。 – 2014-10-30 06:11:05

相關問題