【问题标题】:Postgresql creating users with a functionPostgresql 用函数创建用户
【发布时间】:2018-06-04 16:51:42
【问题描述】:

我目前无法在函数中创建 postgresql 数据库用户。 背景: 我有一个 Java Swing 应用程序,我的目标是开发一个菜单来创建、更改和删除数据库用户。为了使它更安全一点,我创建了一个角色“usermanagement”,并且只允许该角色的成员使用该功能来创建用户。该角色还包含正确的“createuser”

查询运行没有任何问题,但它没有创建新用户......所以我不知道它有什么问题。

这就是我尝试使用我的功能的方式:

SELECT create_databaseuser(v_username := 'thisname' ,v_password := 'pwpwpw');

谁能帮忙?

这是我的代码:

-- Function: public.create_databaseuser(text, text)

-- DROP FUNCTION public.create_databaseuser(text, text);

CREATE OR REPLACE FUNCTION public.create_databaseuser(
    v_username text,
    v_password text)
  RETURNS numeric AS
$BODY$
DECLARE
    r_id numeric;
BEGIN
    --CREATE ROLE v_username LOGIN
    --PASSWORD 'v_password' NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION;

    EXECUTE 'CREATE USER ' || v_username || ' WITH PASSWORD ' || v_password;
-- Alternative:CREATE ROLE v_username LOGIN PASSWORD v_password NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION;

    return 1;
    -- Simple Exception
EXCEPTION
    WHEN others THEN
        RETURN 0;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE SECURITY DEFINER
  COST 100;
ALTER FUNCTION public.create_databaseuser(text, text)
  OWNER TO postgres;

【问题讨论】:

标签: postgresql function user-management


【解决方案1】:

注意STRICT (returns NULL on NULL input),使用FORMAT() 来帮助解决 SQL 注入问题,并正确引用输入。输入参数“v_username”被修改为NAME类型,以匹配pg_catalog.pg_roles中的类型。

DROP FUNCTION IF EXISTS public.create_databaseuser(NAME, TEXT);

CREATE OR REPLACE FUNCTION public.create_databaseuser(
    v_username NAME,
    v_password TEXT)
RETURNS smallint AS
$BODY$
DECLARE
BEGIN
    EXECUTE FORMAT('CREATE ROLE "%I" LOGIN PASSWORD ''%L''', v_username, v_password);
    RETURN 1;
    -- Simple Exception
EXCEPTION
    WHEN others THEN
        RETURN 0;
END;
$BODY$
LANGUAGE plpgsql STRICT VOLATILE SECURITY DEFINER
COST 100;

ALTER FUNCTION public.create_databaseuser(NAME, TEXT) OWNER TO postgres;


select rolname from pg_catalog.pg_roles order by 1;
SELECT create_databaseuser(v_username := 'thisname' ,v_password := 'pwpwpw');
select rolname from pg_catalog.pg_roles order by 1;

【讨论】:

  • 非常感谢。这是工作。与此同时,我只是在我的应用程序中使用了普通的 sql,但现在我可以更改它并使用更好的功能:)
  • 如果我想使用纯数字作为密码,您还有什么建议吗?我用“pw123”调用该函数,它可以工作,但“12345”不工作。实际上,如果发现它正在工作。但在那之后 pw 不会是 12345。当我用 pgadmin 和我的函数更改密码时,我检查了 md5 哈希值。之后密码存储为“12345”。所以我可以用函数内部的 reg 表达式来解决这个问题。现在,如果我想更进一步并使用像 $ 这样的特殊字符,它就不能正常工作了。我该如何解决这个问题?
  • 密码应该被替换为%L(用于文字),而不是%I(用于标识符)。我已经编辑了要修复的函数体。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-14
  • 2015-10-18
  • 2017-03-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多