14. Infraestrutura de autenticação

Dica

Os trechos de código desta página precisam das seguintes importações se você estiver fora do console do pyqgis:

 1from qgis.core import (
 2  QgsApplication,
 3  QgsRasterLayer,
 4  QgsAuthMethodConfig,
 5  QgsDataSourceUri,
 6  QgsPkiBundle,
 7  QgsMessageLog,
 8)
 9
10from qgis.gui import (
11    QgsAuthAuthoritiesEditor,
12    QgsAuthConfigEditor,
13    QgsAuthConfigSelect,
14    QgsAuthSettingsWidget,
15)
16
17from qgis.PyQt.QtWidgets import (
18    QWidget,
19    QTabWidget,
20)
21
22from qgis.PyQt.QtNetwork import QSslCertificate

14.1. Introdução

A referência do usuário da infraestrutura de autenticação pode ser lida no Manual do Usuário no parágrafo Visão Geral do Sistema de Autenticação.

Este capítulo descreve as práticas recomendadas para usar o sistema de autenticação da perspectiva do desenvolvedor.

O sistema de autenticação é amplamente utilizado no QGIS Desktop pelos provedores de dados sempre que são necessárias credenciais para acessar um recurso específico, por exemplo, quando uma camada estabelece uma conexão com um banco de dados Postgres.

Existem também alguns widgets na biblioteca QGIS que os desenvolvedores de complementos podem usar para integrar facilmente a infraestrutura de autenticação ao seu código:

Uma boa referência de código pode ser lida na infraestrutura de autenticação tests code.

Aviso

Due to the security constraints that were taken into account during the authentication infrastructure design, only a selected subset of the internal methods are exposed to Python.

14.2. Glossário

Aqui estão algumas definições dos objetos mais comuns tratados neste capítulo.

Master Password

Senha para permitir acesso e descriptografia de credenciais armazenadas no Banco de Dados de Autenticação QGIS

Banco de Dados de Autenticação

O Master Password banco de dados criptografado sqlite qgis-auth.db onde Authentication Configuration são armazenados, como por exemplo, usuário/senha, certificados e chaves pessoais, Autoridades de Certificação

Banco de Dados de Autenticação

Authentication Database

Configuração de Autenticação

Um conjunto de dados de autenticação, dependendo de Authentication Method, como por exemplo, o Método de autenticação básica armazena o par de usuário/senha.

Authentication Config

Authentication Configuration

Método de Autenticação

Um método específico usado para se autenticar. Cada método possui seu próprio protocolo usado para obter o nível autenticado. Cada método é implementado como uma biblioteca compartilhada carregada dinamicamente durante o init da infraestrutura de autenticação QGIS.

14.3. QgsAuthManager o ponto de entrada

O singleton QgsAuthManager é o ponto de entrada para usar as credenciais armazenadas no QGIS Authentication DB criptografado, i.e. o arquivo qgis-auth.db sob a pasta ativa user profile.

Essa classe cuida da interação do usuário: pedindo para definir uma master password ou usando-a de forma transparente para acessar informações armazenadas criptografadas.

14.3.1. Inicie o gerente e defina a master password

O trecho a seguir fornece um exemplo para definir a master password para abrir o acesso às configurações de autenticação. Os comentários do código são importantes para entender o trecho.

 1authMgr = QgsApplication.authManager()
 2
 3# check if QgsAuthManager has already been initialized... a side effect
 4# of the QgsAuthManager.init() is that AuthDbPath is set.
 5# QgsAuthManager.init() is executed during QGIS application init and hence
 6# you do not normally need to call it directly.
 7if authMgr.authenticationDatabasePath():
 8    # already initialized => we are inside a QGIS app.
 9    if authMgr.masterPasswordIsSet():
10        msg = 'Authentication master password not recognized'
11        assert authMgr.masterPasswordSame("your master password"), msg
12    else:
13        msg = 'Master password could not be set'
14        # The verify parameter checks if the hash of the password was
15        # already saved in the authentication db
16        assert authMgr.setMasterPassword("your master password",
17                                          verify=True), msg
18else:
19    # outside qgis, e.g. in a testing environment => setup env var before
20    # db init
21    os.environ['QGIS_AUTH_DB_DIR_PATH'] = "/path/where/located/qgis-auth.db"
22    msg = 'Master password could not be set'
23    assert authMgr.setMasterPassword("your master password", True), msg
24    authMgr.init("/path/where/located/qgis-auth.db")

14.3.2. Preencha o authdb com uma nova entrada de Configuração de Autenticação

Qualquer credencial armazenada é uma instância de Authentication Configuration da classe QgsAuthMethodConfig acessada usando uma string exclusiva como a que segue:

authcfg = 'fm1s770'

essa string é gerada automaticamente ao criar uma entrada usando a API ou a GUI do QGIS, mas pode ser útil configurá-la manualmente para um valor conhecido caso a configuração precise ser compartilhada (com credenciais diferentes) entre vários usuários em uma organização.

QgsAuthMethodConfig is the base class for any Authentication Method. Any Authentication Method sets a configuration hash map where authentication information will be stored. Hereafter a useful snippet to store PKI-path credentials for a hypothetical alice user:

 1authMgr = QgsApplication.authManager()
 2# set alice PKI data
 3config = QgsAuthMethodConfig()
 4config.setName("alice")
 5config.setMethod("PKI-Paths")
 6config.setUri("https://example.com")
 7config.setConfig("certpath", "path/to/alice-cert.pem" )
 8config.setConfig("keypath", "path/to/alice-key.pem" )
 9# check if method parameters are correctly set
10assert config.isValid()
11
12# register alice data in authdb returning the ``authcfg`` of the stored
13# configuration
14authMgr.storeAuthenticationConfig(config)
15newAuthCfgId = config.id()
16assert newAuthCfgId

14.3.2.1. Métodos de Autenticação disponíveis

Authentication Method libraries are loaded dynamically during authentication manager init. Available authentication methods are:

  1. Basic Autenticação de usuário e senha

  2. Esri-Token ESRI token based authentication

  3. Identity-Cert Autenticação de certificado de identidade

  4. OAuth2 OAuth2 authentication

  5. PKI-Paths autenticação de caminhos PKI

  6. PKI-PKCS#12 PKI PKCS#12 autenticação

14.3.2.2. Preencher Autoridades

1authMgr = QgsApplication.authManager()
2# add authorities
3cacerts = QSslCertificate.fromPath( "/path/to/ca_chains.pem" )
4assert cacerts is not None
5# store CA
6authMgr.storeCertAuthorities(cacerts)
7# and rebuild CA caches
8authMgr.rebuildCaCertsCache()
9authMgr.rebuildTrustedCaCertsCache()

14.3.2.3. Gerenciar pacotes configuráveis ​​de PKI com QgsPkiBundle

Uma classe de conveniência para empacotar pacotes configuráveis ​​PKI compostos na cadeia SslCert, SslKey e CA é a classe QgsPkiBundle. A seguir, um trecho para obter uma senha protegida:

1# add alice cert in case of key with pwd
2caBundlesList = []  # List of CA bundles
3bundle = QgsPkiBundle.fromPemPaths( "/path/to/alice-cert.pem",
4                                     "/path/to/alice-key_w-pass.pem",
5                                     "unlock_pwd",
6                                     caBundlesList )
7assert bundle is not None
8# You can check bundle validity by calling:
9# bundle.isValid()

Consulte a documentação da classe QgsPkiBundle para extrair cert/key/CAs do pacote.

14.3.3. Remover uma entrada de authdb

Podemos remover uma entrada de Authentication Database usando seu identificador authcfg com o seguinte trecho:

authMgr = QgsApplication.authManager()
authMgr.removeAuthenticationConfig( "authCfg_Id_to_remove" )

14.3.4. Leave authcfg expansion to QgsAuthManager

A melhor maneira de usar um Authentication Config armazenado em Authentication DB é referenciá-lo com o identificador exclusivo authcfg. Expandir significa convertê-lo de um identificador para um conjunto completo de credenciais. A melhor prática para usar os Authentication Configs armazenados, é deixá-los gerenciados automaticamente pelo gerenciador de autenticação. O uso comum de uma configuração armazenada é conectar-se a um serviço habilitado para autenticação, como um WMS ou WFS ou a uma conexão de banco de dados.

Nota

Take into account that not all QGIS data providers are integrated with the Authentication infrastructure. Each authentication method, derived from the base class QgsAuthMethod and support a different set of Providers. For example the certIdentity() method supports the following list of providers:

authM = QgsApplication.authManager()
print(authM.authMethod("Identity-Cert").supportedDataProviders())

Sample output:

['ows', 'wfs', 'wcs', 'wms', 'postgres']

Por exemplo, para acessar um serviço WMS usando credenciais armazenadas identificadas com authcfg = 'fm1s770', basta usar o authcfg no URL da fonte de dados, como no seguinte trecho:

 1authCfg = 'fm1s770'
 2quri = QgsDataSourceUri()
 3quri.setParam("layers", 'usa:states')
 4quri.setParam("styles", '')
 5quri.setParam("format", 'image/png')
 6quri.setParam("crs", 'EPSG:4326')
 7quri.setParam("dpiMode", '7')
 8quri.setParam("featureCount", '10')
 9quri.setParam("authcfg", authCfg)   # <---- here my authCfg url parameter
10quri.setParam("contextualWMSLegend", '0')
11quri.setParam("url", 'https://my_auth_enabled_server_ip/wms')
12rlayer = QgsRasterLayer(str(quri.encodedUri(), "utf-8"), 'states', 'wms')

Em maiúsculas, o provedor wms cuidará para expandir o parâmetro URI authcfg com credencial antes de definir a conexão HTTP.

Aviso

O desenvolvedor precisaria deixar a expansão authcfg para QgsAuthManager, dessa forma ele garantirá que a expansão não seja feita muito cedo.

Geralmente, uma string de URI, criada usando a classe QgsDataSourceURI, é usada para definir uma fonte de dados da seguinte maneira:

authCfg = 'fm1s770'
quri = QgsDataSourceUri("my WMS uri here")
quri.setParam("authcfg", authCfg)
rlayer = QgsRasterLayer( quri.uri(False), 'states', 'wms')

Nota

O parâmetro False é importante para evitar a expansão completa do URI do ID authcfg presente no URI.

14.3.4.1. Exemplos PKI com outros provedores de dados

Outro exemplo pode ser lido diretamente nos testes QGIS anteriores, como em test_authmanager_pki_ows ou test_authmanager_pki_postgres.

14.4. Adapte complementos para usar a infraestrutura de autenticação

Muitos complementos de terceiros estão usando o enableplib2 ou outras bibliotecas de rede Python para gerenciar conexões HTTP em vez de integrar-se com QgsNetworkAccessManager e sua integração relacionada à Infra-estrutura de autenticação.

Para facilitar essa integração, uma função auxiliar Python foi criada chamada NetworkAccessManager. Seu código pode ser encontrado aqui.

Essa classe auxiliar pode ser usada como no seguinte trecho:

1http = NetworkAccessManager(authid="my_authCfg", exception_class=My_FailedRequestError)
2try:
3  response, content = http.request( "my_rest_url" )
4except My_FailedRequestError, e:
5  # Handle exception
6  pass

14.5. GUIs de autenticação

Neste parágrafo, estão listadas as GUIs disponíveis úteis para integrar a infraestrutura de autenticação em interfaces personalizadas.

14.5.1. GUI para selecionar credenciais

If it’s necessary to select a Authentication Configuration from the set stored in the Authentication DB it is available in the GUI class QgsAuthConfigSelect.

../../_images/QgsAuthConfigSelect.png

e pode ser usado como no seguinte trecho:

1# create the instance of the QgsAuthConfigSelect GUI hierarchically linked to
2# the widget referred with `parent`
3parent = QWidget()  # Your GUI parent widget
4gui = QgsAuthConfigSelect( parent, "postgres" )
5# add the above created gui in a new tab of the interface where the
6# GUI has to be integrated
7tabGui = QTabWidget()
8tabGui.insertTab( 1, gui, "Configurations" )

O exemplo acima é retirado da fonte do QGIS code. O segundo parâmetro do construtor da GUI refere-se ao tipo de provedor de dados. O parâmetro é usado para restringir os Authentication Methods compatíveis com o provedor especificado.

14.5.2. GUI do Editor de Autenticação

A GUI completa usada para gerenciar credenciais, autoridades e acessar os utilitários de autenticação é gerenciada pela classe QgsAuthEditorWidgets.

../../_images/QgsAuthEditorWidgets.png

e pode ser usado como no seguinte trecho:

1# create the instance of the QgsAuthEditorWidgets GUI hierarchically linked to
2# the widget referred with `parent`
3parent = QWidget()  # Your GUI parent widget
4gui = QgsAuthConfigSelect( parent )
5gui.show()

An integrated example can be found in the related test.

14.5.3. GUI do Editor de Autoridades

A GUI used to manage only authorities is managed by the QgsAuthAuthoritiesEditor class.

../../_images/QgsAuthAuthoritiesEditor.png

e pode ser usado como no seguinte trecho:

1# create the instance of the QgsAuthAuthoritiesEditor GUI hierarchically
2#  linked to the widget referred with `parent`
3parent = QWidget()  # Your GUI parent widget
4gui = QgsAuthAuthoritiesEditor( parent )
5gui.show()