问题
I know that I can use views to grant access to a subset of attributes in a table. But how can I grant access to particular tuples only? Say I have a table of registered students, a username attribute and then some other like degree_status, how do I grant access so that user A can only select from the table a tuple corresponding to username A ? I have a database exam and I'm studying some past papers and I came across this question but I don't know how to answer it and I cant find how to do it from my book "Dtabase System: A practical Approach to Database Design, Implementation and Management'
Thanks any help is much appreciated!
Matt
回答1:
Say that you got :
Table items (item_id, ...)
Table users (user_id, ...)
Table users_permissions( user_id, item_id, perm_type )
You could create a VIEW like this :
SELECT i.*, p.perm_type
FROM items JOIN users_permissions USING (item_id)
WHERE user_id = get_current_user_id();
Users can select from this view but not remove the WHERE and JOIN restricting the permissions.
The get_current_user_id() function is likely to be the major problem ;)
回答2:
Along the lines of peufeu's answer, in Postgresql the current user name is available through the function current_user. So a view
CREATE VIEW available_bigtable AS
SELECT * FROM bigtable
WHERE username = current_user;
looks like it does what you need. Grant SELECT
to everyone on the view, but to no one (except admins) on the underlying bigtable
.
回答3:
The Veil project provides a framework for row-level access control in PostgreSQL.
回答4:
How about creating a function that takes the user id and returns the subset of rows he has access to?
CREATE FUNCTION user_items(integer) RETURNS SETOF items AS $$
SELECT * FROM items WHERE user_id = $1
$$ LANGUAGE SQL;
SELECT * FROM user_items(55); # 55 being the user id
edit Thinking about it more, this could cause quite a performance hit, as the user_id condition would be applied to the whole data set, prior to any other "user-land" conditions.
For example, SELECT * FROM user_items(55) WHERE id=45
would first filter the entire table for user items, and only than find the ID on that subset.
With views, the query planner can decide on the optimal order to evaluate the conditions (where he'll probably filter for the ID first, than for user id). When using a function like I suggested, postgres can't do that.
来源:https://stackoverflow.com/questions/6004357/grant-access-to-subset-of-table-to-user-on-postgresql