我想要掌握在支持Web应用程序的多租户数据库中使用新行级安全功能的最佳方法.
目前,该应用程序有几个不同的ROLE可用,具体取决于它尝试采取的操作.
一旦应用程序使用自己的ROLE建立连接,应用程序就会将身份验证参数(由用户提供)传递到不同的函数中,这些函数根据用户提供的身份验证参数筛选出行.该系统旨在与成千上万的用户合作,它似乎工作; 然而,它是狡猾的(而且很慢).
似乎如果我想使用新的行级安全功能,我需要为每个真实世界用户(不仅仅是Web应用程序)创建一个新的ROLE来访问数据库.
它是否正确?如果是这样,在数据库中创建数千个ROLE是一个好主意吗?
从评论中的a_horse_with_no_name链接更新(谢谢,该线程是正确的):
CREATE USER application;
CREATE TABLE t1 (id int primary key, f1 text, app_user text);
INSERT INTO t1 VALUES(1,'a','bob');
INSERT INTO t1 VALUES(2,'b','alice');
ALTER TABLE t1 ENABLE ROW LEVEL SECURITY;
CREATE POLICY P ON t1 USING (app_user = current_setting('app_name.app_user'));
GRANT SELECT ON t1 TO application;
SET SESSION AUTHORIZATION application;
SET app_name.app_user = 'bob';
SELECT * FROM t1;
id | f1 | app_user
----+----+----------
1 | a | bob
(1 row) …Run Code Online (Sandbox Code Playgroud) 我正在运行一个在添加记录时逐渐变慢的查询.通过自动过程(bash调用psql)连续添加记录.我想纠正这个瓶颈; 但是,我不知道我最好的选择是什么.
Hour Count Duration Avg duration
00 9,990 10m3s 60ms <---ignore this hour
02 1 60ms 60ms <---ignore this hour
03 4,638 1m54s 24ms <---queries begin with table empty
04 30,991 55m49s 108ms <---first full hour of queries running
05 13,497 58m3s 258ms
06 9,904 58m32s 354ms
07 10,542 58m25s 332ms
08 8,599 58m42s 409ms
09 7,360 58m52s 479ms
10 6,661 58m57s 531ms
11 6,133 59m2s 577ms
12 5,601 59m6s 633ms
13 5,327 59m9s 666ms
14 …Run Code Online (Sandbox Code Playgroud) sql postgresql database-design postgresql-performance postgresql-9.4
我已多次安装PostgreSQL 9.x和PostGIS 1.5/2.0,从未遇到过这个问题.
我刚刚启动并运行了一个新的CentOS 6.3服务器,并且我按照预期运行了Postgres 9.3.我跑了
yum install postgis2_93
Run Code Online (Sandbox Code Playgroud)
我可以看到文件
/usr/pgsql-9.3/share/contrib/
Run Code Online (Sandbox Code Playgroud)
但是,当我跑
CREATE EXTENSION postgis;
Run Code Online (Sandbox Code Playgroud)
我收到
ERROR: could not open extension control file "/usr/pgsql-9.3/share/extension/postgis.control": No such file or directory
Run Code Online (Sandbox Code Playgroud)
我使用的教程(#1,#2)没有显示安装PostGIS和创建扩展之间的任何步骤.
我错过了什么?
在正常情况下,将NULL值与任何其他值进行比较会产生另一个NULL值.
SELECT NULL = NULL;
Run Code Online (Sandbox Code Playgroud)
返回 NULL
在比较任意行时,这(大多数情况下)是正确的,如文档9.23.5中所述.行构造函数比较:
SELECT ROW(1, NULL, 'baz text') = ROW(1, NULL, 'baz text');
Run Code Online (Sandbox Code Playgroud)
返回 NULL
但是,在比较定义良好的复合类型时,NULL值被视为相等.
CREATE TYPE test_type AS (
foo INTEGER,
bar BIGINT,
baz TEXT
);
SELECT (1, NULL, 'baz text')::test_type = (1, NULL, 'baz text')::test_type;
Run Code Online (Sandbox Code Playgroud)
返回 TRUE
这种行为似乎没有记录(我看过并发现没有对行为的引用).
我想使用此行为来实现一些业务规则,并希望确保这样做是安全的.
我需要加密PostgreSQL 9.6数据库中的一些列.被加密的数据本质上是敏感的; 但是,数据不是密码或其他身份验证凭据.需要对这些数据进行解密,以供用户进行统计分析和消费.
看完几个问题和答案后:
......并考虑以下评论:
...使用pgcrypto模块似乎最大的问题是在同一个数据库中存储密钥.
是否与将密钥存储在不同数据库中并通过外部数据包装器(如Postgresql_FDW)访问它的最佳实践一致?
我有一些代表不同"行动"的数据.这些"行动"共同构成"事件".
数据如下所示:
EventID | UserID | Action | TimeStamp
--------------+------------+------------+-------------------------
1 | 111 | Start | 2012-01-01 08:00:00
1 | 111 | Stop | 2012-01-01 08:59:59
1 | 999 | Start | 2012-01-01 09:00:00
1 | 999 | Stop | 2012-01-01 09:59:59
1 | 111 | Start | 2012-01-01 10:00:00
1 | 111 | Stop | 2012-01-01 10:30:00
Run Code Online (Sandbox Code Playgroud)
如您所见,每个单独的"事件"都由一个或多个"动作"组成(或者我认为它们是"子事件").
我需要识别每个'子事件'并给它一个标识符.这就是我要找的东西:
EventID | SubeventID | UserID | Action | TimeStamp
--------------+----------------+------------+------------+-------------------------
1 | 1 | 111 | Start | 2012-01-01 …Run Code Online (Sandbox Code Playgroud) 我使用Postgres 9.3数据库作为 Web 应用程序的后端。我使用PHP 5.5.7连接到数据库并为前端 AJAX 调用返回 JSON。
我不是安全专家;然而,我熟悉 PHP 的新password_*()功能,并且对幕后发生的事情有很强的把握。我也熟悉 Postgres 扩展pgcrypto和相关crypt()功能。
我的问题是,使用 PHP 或 Postgres 来哈希密码是否有意义?
我很好奇这些函数有何不同,所以我用 PHP 做了一个密码哈希,然后将其交给 Postgres,看看 Postgres 是否使用相同的算法。给定相同的参数,Postgres 与 PHP 相比返回了不同的结果(这并不意外,但需要注意)。
password_hash('password', PASSWORD_BCRYPT, ["cost" => 15]);
Run Code Online (Sandbox Code Playgroud)
输出: $2y$15$o8JufrnVXoob2NKiEGx6.uI4O2D4VcaAmY7WtNq5zPFiJow4KohGu
SELECT '$2y$15$o8JufrnVXoob2NKiEGx6.uI4O2D4VcaAmY7WtNq5zPFiJow4KohGu' = crypt('password', '$2y$15$o8JufrnVXoob2NKiEGx6.uI4O2D4VcaAmY7WtNq5zPFiJow4KohGu')
Run Code Online (Sandbox Code Playgroud)
输出: 假
鉴于这些过程不同,我想知道是否一个比另一个更好?多一个还是少一个安全?
其他一些想法:
我目前将所有逻辑存储在数据库中(在视图、函数、约束等中),因此如果我需要使用不同的前端,我不必担心丢失逻辑。在 PHP 中计算密码哈希实际上要求所有请求都通过 PHP 来访问数据库。
另一方面,将逻辑放入数据库将使我能够灵活地使用其他连接选项;但是,所有 Postgres 查询都会被记录。由于复制中使用了 WAL,我无法禁用日志。这似乎是一个很大的安全漏洞。
我走在正确的轨道上吗?我缺少什么?
我刚刚查看了另一个消息线程并找到了更多信息。
我有一张大的(3000万行)简单的桌子...
CREATE TABLE "Foo"."Bar" (
"BarID" BIGSERIAL PRIMARY KEY,
"DateTime" TIMESTAMP NOT NULL,
"Bar" TEXT NOT NULL
);
Run Code Online (Sandbox Code Playgroud)
...一个简单的索引:
CREATE INDEX ON "Foo"."Bar"("DateTime");
Run Code Online (Sandbox Code Playgroud)
...和一个简单的问题:
在2015年的第一个小时,哪些"BarID"值具有"DateTime"价值?
因此,我进行了以下查询#1:
SELECT
"Bar"."BarID"
FROM
"Foo"."Bar"
WHERE
"Bar"."DateTime" <@ TSRANGE('2015-01-01 00:00:00', '2015-01-01 01:00:00');
Run Code Online (Sandbox Code Playgroud)
...以及此查询#2:
SELECT
"Bar"."BarID"
FROM
"Foo"."Bar"
WHERE
"Bar"."DateTime" BETWEEN '2015-01-01 00:00:00' AND '2015-01-01 01:00:00';
Run Code Online (Sandbox Code Playgroud)
查询#1在60秒内通过序列扫描运行。
使用索引扫描,查询2在0.02秒内运行。
我尝试制作另一个USING GiST没有改善的索引。
是什么赋予了?
我有一些数据(按"TimeStamp"排序),如下所示:
Key | TimeStamp | Column3 | ColumnN
--------------+-------------------------+-------------+--------------
1 | 2012-01-01 08:00:23 | ... | ...
2 | 2012-01-01 08:01:07 | ... | ...
3 | 2012-01-01 08:02:56 | ... | ...
6 | 2012-01-01 08:02:56 | ... | ...
4 | 2012-01-01 08:03:39 | ... | ...
5 | 2012-01-01 08:04:32 | ... | ...
Run Code Online (Sandbox Code Playgroud)
我需要为每条记录选择"TimeStamp" 的下一个值(不仅仅是下一行).
例如,以上数据如下所示:
Key | Begin | End | Column3 | ColumnN
--------------+-------------------------+-------------------------+-------------+--------------
1 | 2012-01-01 08:00:23 | 2012-01-01 …Run Code Online (Sandbox Code Playgroud) 我一直在到处(google、stackoverflow 等)寻找一些关于如何使用 PostgreSQLpg_read_binary_file()函数的文档。
我能找到的唯一有意义的是官方文档中的这个页面。
每次尝试使用此功能时,都会出现错误。
例如:
SELECT pg_read_binary_file('/some/path/and/file.gif');
ERROR: absolute path not allowed
Run Code Online (Sandbox Code Playgroud)
或者
SELECT pg_read_binary_file('file.gif');
ERROR: could not stat file "file.gif": No such file or directory
Run Code Online (Sandbox Code Playgroud)
我是否需要将我的文件放在特定目录中才能让 Postgres 访问它?如果是什么目录?
如果重要的话,我查看这个函数的原因是因为我试图将文件插入数据库而不做疯狂的事情。