AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 25357
Accepted
Chris Travers
Chris Travers
Asked: 2012-10-04 05:08:02 +0800 CST2012-10-04 05:08:02 +0800 CST 2012-10-04 05:08:02 +0800 CST

Escolha da abordagem de autenticação para aplicativo financeiro no PostgreSQL

  • 772

Primeiro alguns antecedentes.

O projeto LedgerSMB é um projeto de software de contabilidade financeira de código aberto executado no PostgreSQL. Implementamos uma quantidade muito grande de lógica de negócios em funções definidas pelo usuário, que atuam como a principal ferramenta de mapeamento entre os métodos de objeto do programa e o comportamento do banco de dados. Atualmente, usamos usuários de banco de dados como usuários de autenticação, em parte por opção (isso permite uma lógica de segurança centralizada, para que outras ferramentas possam ser escritas e reutilizar as permissões dadas aos usuários) e em parte por necessidade (depois que bifurcamos do SQL-Ledger, há não havia muitas opções para atualizar a segurança nessa base de código).

Isso nos dá acesso a um número razoável de opções de conexão única às quais o PostgreSQL tem acesso, do LDAP ao Kerberos 5. Podemos até usar o PAM no que diz respeito às senhas. Também nos permite reutilizar permissões ao integrar com outros aplicativos ou permitir outras interfaces de cliente. Para um aplicativo de contabilidade financeira, isso parece uma vitória líquida.

Há custos óbvios envolvidos. Para o aplicativo da web, estamos muito limitados aos tipos de autenticação http que podem ser suportados. DIGEST, por exemplo, está totalmente fora. O BASIC funciona e poderíamos implementar o KRB5 com bastante facilidade (pretendo ter isso suportado e funcionando imediatamente para 1.4). Medidas de autenticação muito fortes não podem ser gerenciadas adequadamente diretamente, embora provavelmente possamos corrigi-las, se necessário (por exemplo, BASIC + certificado SSL do lado do cliente com um cn correspondente ao nome do usuário e uma raiz específica ca).

Ao mesmo tempo, recebemos muitas críticas, principalmente do pessoal do desenvolvimento e, mais ocasionalmente, de dba's que me dizem que o aplicativo deve ser a barreira de segurança, não o banco de dados. Minha opinião ainda é que um perímetro de segurança menor geralmente é melhor, que a reutilização da lógica de negócios e da lógica de segurança andam juntas e que me parece perigoso reutilizar a lógica de negócios sem reutilizar a lógica de segurança no mesmo nível do programa.

Estou perdendo alguma compensação importante aqui? Existem pegadinhas que não estou considerando?

database-design postgresql
  • 1 1 respostas
  • 3575 Views

1 respostas

  • Voted
  1. Best Answer
    Craig Ringer
    2012-10-04T18:00:14+08:002012-10-04T18:00:14+08:00

    Acho que você está confundindo autenticação e autorização .

    Concordo plenamente que é sensato manter o modelo de segurança no banco de dados, especialmente porque o LedgerSMB foi projetado tendo em mente o acesso de vários clientes. A menos que você planeje usar 3 camadas com uma camada de middleware, faz todo o sentido ter usuários como funções de banco de dados, especialmente para algo como um aplicativo de contabilidade.

    Isso não significa que você precisa autenticar os usuários no banco de dados usando um método de autenticação suportado pelo PostgreSQL. Seus usuários de banco de dados, funções e concessões podem ser usados ​​para autorização somente se você quiser.

    Veja como funciona para uma interface do usuário da web, por exemplo:

    • janeconecta-se ao servidor web ui e autentica usando qualquer método desejado, por exemplo, handshake de certificado de cliente HTTPS X.509 e autenticação DIGEST. O servidor agora tem uma conexão de um usuário que ele aceita é realmente jane.

    • O servidor se conecta ao PostgreSQL usando um nome de usuário/senha fixo (ou Kerberos ou o que você quiser), autenticando-se no servidor db como o usuário webui. O servidor db confia webuipara autenticar seus usuários, portanto webui, recebeu GRANTs apropriados (veja abaixo).

    • Nessa conexão o servidor usa SET ROLE jane;para assumir o nível de autorização do usuário jane. Até que RESET ROLE;ou outro SET ROLEseja executado, a conexão está operando com os mesmos direitos de acesso que janee SELECT current_user()etc reportará jane.

    • O servidor mantém a associação entre a conexão do banco de dados em que se encontra SET ROLEe janea sessão web do usuário jane, não permitindo que essa conexão PostgreSQL seja utilizada por outras conexões com outros usuários sem um novo SET ROLEmeio.

    Agora você está autenticando fora do servidor, mas mantendo a autorização no servidor. Pg precisa saber quais usuários existem, mas não precisa de senhas ou métodos de autenticação para eles.

    Ver:

    • SET SESSION AUTHORIZATION
    • SET ROLE
    • GRANT

    Detalhes

    O servidor webui controla a execução das consultas e não permite a janeexecução de SQL bruto (espero!), Portanto jane, não pode ser feito RESET ROLE; SET ROLE special_admin_user;pela interface do usuário da web. Para maior segurança, eu adicionaria um filtro de instrução ao servidor que rejeitou SET ROLEe RESET ROLE, a menos que a conexão estivesse ou entrasse em um pool de conexões não atribuídas.

    Você ainda está livre para usar autenticação direta para Pg em outros clientes; você pode misturar e combinar livremente. Você apenas tem que dar GRANTao webuiusuário os direitos de SET ROLEusuários que podem fazer login via web e, em seguida, dar a esses usuários quaisquer CONNECTdireitos normais, senhas, etc. que desejar. Se você quiser torná-los apenas na web, REVOKEseus CONNECTdireitos no banco de dados (e de public).

    Para facilitar essa divisão de autenticação/autorização, tenho uma função especial para assume_any_usercada GRANTusuário recém-criado. Em seguida, chego GRANT assume_any_userao nome de usuário real usado por coisas como um front-end da Web confiável, dando a eles o direito de se tornarem qualquer usuário que desejarem.

    É importante criar assume_any_useruma NOINHERITfunção, para que o webuiusuário ou o que quer que seja não tenha privilégios próprios e só possa atuar no banco de dados quando for SET ROLEpara um usuário real. Sob nenhuma circunstância deve webuiser um superusuário ou proprietário do banco de dados .

    Se você estiver fazendo um pool de conexões, poderá usar SET LOCAL ROLEpara definir a função somente dentro de uma transação, para que possa retornar as conexões ao pool após COMMITou ROLLBACK. Cuidado, isso RESET ROLEainda funciona, então ainda não é seguro deixar o cliente executar qualquer SQL que desejar.

    SET SESSION AUTHORIZATIONé a versão relacionada, mas mais forte deste comando. Não requer associação de função, mas é um comando apenas de superusuário. Você não deseja que sua interface do usuário da web se conecte como um superusuário. Ele pode ser revertido com RESET SESSION AUTHORIZATION, SET SESSION AUTHORIZATION DEFAULTou SET SESSION AUTHORIZATION theusernamepara recuperar os direitos de superusuário, para que também não seja uma barreira de segurança que reduza os privilégios.

    Um comando que funcionasse como SET SESSION AUTHORIZATION, mas fosse irreversível e funcionaria se você fosse um membro da função, mas não um superusuário, seria ótimo. Neste ponto, não há um, mas você ainda pode separar autenticação e autorização muito bem se for cuidadoso.

    Exemplo e explicação

    CREATE ROLE dbowner NOLOGIN;
    CREATE TABLE test_table(x text);
    INSERT INTO test_table(x) VALUES ('bork');
    ALTER TABLE test_table OWNER TO dbowner;
    
    CREATE ROLE assume_any_user NOINHERIT NOLOGIN;
    CREATE ROLE webui LOGIN PASSWORD 'somepw' IN ROLE assume_any_user;
    
    CREATE ROLE jane LOGIN PASSWORD 'somepw';
    GRANT jane TO assume_any_user;
    GRANT ALL ON TABLE test_table TO jane;
    
    CREATE ROLE jim LOGIN PASSWORD 'somepw';
    GRANT jim TO assume_any_user;
    

    Agora conecte como webui. Observe que você não pode fazer nada, test_tablemas pode e , SET ROLEem seguida , pode acessar :janetest_table

    $ psql -h 127.0.0.1 -U webui regress
    Password for user webui:
    
    regress=> SELECT session_user, current_user;
     session_user | current_user 
    --------------+--------------
     webui        | webui
    (1 row)
    
    
    
    regress=> SELECT * FROM test_table;
    ERROR:  permission denied for relation test_table
    
    regress=> SET ROLE jane;
    SET
    
    regress=> SELECT session_user, current_user;
     session_user | current_user 
    --------------+--------------
     webui        | jane
    (1 row)
    
    regress=> SELECT * FROM test_table;
      x   
    ------
     bork
    (1 row)
    

    Observe que pode webui , mesmo quando já foi dado e mesmo que não tenha sido autorizado a assumir a função . define seu ID de usuário efetivo, mas não remove sua capacidade de outras funções, isso é uma propriedade da função à qual você se conectou, não sua função efetiva atual. Conseqüentemente, você deve controlar cuidadosamente o acesso aos comandos e . Não há, AFAIK, nenhuma maneira de obter uma conexão permanente , tornando-se verdadeiramente o usuário-alvo, embora certamente seja bom ter.SET ROLEjimSET ROLEjanejaneGRANTjimSET ROLESET ROLESET ROLERESET ROLESET ROLE

    Comparar:

    $ psql -h 127.0.0.1 -U webui regress
    Password for user webui:
    
    regress=> SET ROLE jane;
    SET
    
    regress=> SET ROLE jim;
    SET
    regress=> SELECT session_user, current_user;
     session_user | current_user 
    --------------+--------------
     webui        | jim
    (1 row)
    

    para:

    $ psql -h 127.0.0.1 -U jane regress
    Password for user jane:
    
    regress=> SET ROLE webui;
    ERROR:  permission denied to set role "webui"
    regress=> SET ROLE jim;
    ERROR:  permission denied to set role "jim"
    

    Isso significa que SET ROLEnão é exatamente o mesmo que fazer login como uma determinada função, algo que você deve ter em mente.

    webuinão pode SET ROLE, dbownerpois não foi GRANTeditado corretamente:

    regress=> SET ROLE dbowner;
    ERROR:  permission denied to set role "dbowner"
    

    portanto, por si só, é bastante impotente, só pode assumir os direitos de outros usuários e somente quando esses usuários tiverem acesso à web ativado.

    • 18

relate perguntas

  • Práticas recomendadas para executar a replicação atrasada do deslocamento de tempo

  • Os procedimentos armazenados impedem a injeção de SQL?

  • Quais são algumas maneiras de implementar um relacionamento muitos-para-muitos em um data warehouse?

  • Sequências Biológicas do UniProt no PostgreSQL

  • Qual é a diferença entre a replicação do PostgreSQL 9.0 e o Slony-I?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como ver a lista de bancos de dados no Oracle?

    • 8 respostas
  • Marko Smith

    Quão grande deve ser o mysql innodb_buffer_pool_size?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    restaurar a tabela do arquivo .frm e .ibd?

    • 10 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Como selecionar a primeira linha de cada grupo?

    • 6 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    bernd_k Quando devo usar uma restrição exclusiva em vez de um índice exclusivo? 2011-01-05 02:32:27 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve