14. Infraestructura de autenticación

Consejo

Los fragmentos de código en esta página necesitan las siguientes adiciones si está fuera de la consola de 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. Introducción

La referencia de Usuario de la infraestructura de Autenticación puede ser leída en el Manual del Usuario en el párrafo Vista general del sistema de Autenticación.

En este capítulo se describen las mejores prácticas para usar el sistema de autenticación desde una perspectiva de desarrollador.

El sistema de autenticación es ampliamente utilizado en QGIS Desktop por los proveedores de datos siempre que se requieren credenciales para acceder a un recurso en particular, por ejemplo, cuando una capa establece una conexión a una base de datos de Postgres.

También hay algunos widgets en la biblioteca de interfaz gráfica de usuario de QGIS que los desarrolladores de complementos pueden usar para integrar fácilmente la infraestructura de autenticación en su código:

Se puede leer una buena referencia de código desde la infraestructura de autenticación tests code.

Advertencia

Debido a las restricciones de seguridad que se tuvieron en cuenta durante el diseño de la infraestructura de autenticación, solo un subconjunto seleccionado de los métodos internos están expuestos a Python.

14.2. Glosario

Aquí hay algunas definiciones de los objetos más comunes tratados en este capítulo.

Contraseña maestra

Contraseña para permitir el acceso y descifrar las credenciales almacenadas en la base de datos de autenticación de QGIS

BBDD de Autenticación

Un Master Password encriptado sqlite db qgis-auth.db donde Authentication Configuration son almacenados. p.ej. usuario/contraseña, certificados personales y claves, Autoridades de certificación

Autenticación BD

Authentication Database

Configuración de Autenticación

Un conjunto de datos de autenticación según Authentication Method. p.ej. El método de Autenticación básica almacena el par de usuario/contraseña.

Configuración de autenticación

Authentication Configuration

Método de autenticación

Un método específico utilizado para autenticarse. Cada método tiene su propio protocolo utilizado para obtener el nivel autenticado. Cada método se implementa como una biblioteca compartida cargada dinámicamente durante el inicio de la infraestructura de autenticación de QGIS.

14.3. QgsAuthManager el punto de entrada

El QgsAuthManager singleton es el punto de entrada para usar las credenciales almacenadas en el QGIS encriptado BBDD Autenticación, es decir, el archivo qgis-auth.db en la carpeta activa perfil de usuario.

Esta clase se encarga de la interacción del usuario: solicitando establecer una contraseña maestra o utilizándola de forma transparente para acceder a la información almacenada cifrada.

14.3.1. Inicie el administrador y configure la contraseña maestra

El siguiente fragmento ofrece un ejemplo para establecer una contraseña maestra para abrir el acceso a la configuración de autenticación. Los comentarios de código son importantes para comprender el fragmento.

 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. Complete authdb con una nueva entrada de configuración de autenticación

Cualquier credencial almacenado es una instancia Authentication Configuration de la clase QgsAuthMethodConfig se accede usando una cadena única como la siguiente:

authcfg = 'fm1s770'

esa cadena se genera automáticamente al crear una entrada utilizando la API o GUI de QGIS, pero podría ser útil establecerla manualmente en un valor conocido en caso de que la configuración deba compartirse (con diferentes credenciales) entre varios usuarios dentro de una organización.

QgsAuthMethodConfig es la clase base para cualquier Método de autenticación. Cualquier método de autenticación establece un mapa hash de configuración donde se almacenará la información de autenticación. A continuación, un fragmento útil para almacenar las credenciales de ruta PKI para un usuario hipotético de Alice:

 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 autenticación disponibles

Authentication Method las bibliotecas se cargan dinámicamente durante el inicio del administrador de autenticación. Los métodos de autenticación disponibles son:

  1. Basic Autenticación de usuario y contraseña

  2. Esri-Token Autenticación basada en token ESRI

  3. Identity-Cert Autenticación del certificado de identidad

  4. OAuth2 autenticación OAuth2

  5. PKI-Paths Autenticación de rutas PKI

  6. PKI-PKCS#12 PKI PKCS#12 Autenticación

14.3.2.2. Populate Authorities

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. Administrar paquetes de PKI con QgsPkiBundle

Una clase de conveniencia para empaquetar paquetes PKI compuestos en cadenas SslCert, SslKey y CA es la clase QgsPkiBundle. A continuación, un fragmento para protegerse con contraseña:

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()

Referirse a documentación de la clase QgsPkiBundle para extraer cert/clave/CAs del paquete.

14.3.3. Borrar una entrada de authdb

Podemos borrar una entrada de Authentication Database usando su identificador authcfg con el siguiente fragmento:

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

14.3.4. Deje la expansión authcfg a QgsAuthManager

La mejor manera de utilizar una Configuración de Autenticación almacenada en BBDD de Autenticación es refiriéndola con el identificador único authcfg. Expandir significa convertirlo de un identificador a un conjunto completo de credenciales. La mejor práctica para usar el Authentication Configs almacenado, es dejarlo administrado automáticamente por el administrador de Autenticación. El uso común de una configuración almacenada es conectarse a un servicio habilitado para autenticación como WMS o WFS oa una conexión de base de datos.

Nota

Tenga en cuenta que no todos los proveedores de datos de QGIS están integrados con la infraestructura de autenticación. Cada método de autenticación, derivado de la clase base QgsAuthMethod y soporta un conjunto diferente de Proveedores. Por ejemplo el método certIdentity() soporta la siguiente lista de proveedores:

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

Salida de muestra:

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

Por ejemplo, para acceder a un servicio WMS usando credenciales almacenadas identificadas con authcfg = 'fm1s770', solo tenemos que usar el authcfg en la URL de la fuente de datos como en el siguiente fragmento:

 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')

En mayúsculas, el proveedor wms se encargará de expandir el parámetro URI authcfg con credencial justo antes de configurar la conexión HTTP.

Advertencia

El desarrollador tendría que dejar la expansión ʻauthcfg` a QgsAuthManager, de esta manera se asegurará de que la expansión no se haga demasiado pronto.

Por lo general, una cadena URI, construida usando la clase QgsDataSourceURI , se utiliza para configurar una fuente de datos de la siguiente manera:

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

Nota

El parámetro False es importante para evitar la expansión completa de URI del id authcfg presente en el URI.

14.3.4.1. Ejemplos PKI con otros proveedores de datos

Otro ejemplo se puede leer directamente en las pruebas de QGIS en sentido ascendente como en test_authmanager_pki_ows o test_authmanager_pki_postgres.

14.4. Adpatar complementos para usar Infraestructura de Autenticación

Muchos complementos de terceros están utilizando httplib2 u otras bibliotecas de red de Python para administrar las conexiones HTTP en lugar de integrarse con QgsNetworkAccessManager y su integración relacionada con la infraestructura de autenticación.

Para facilitar esta integración se ha creado una función auxiliar de Python llamada NetworkAccessManager. Su código se puede encontrar aquí.

Esta clase auxiliar se puede utilizar como en el siguiente fragmento:

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. Autenticación IGUs

En este párrafo se enumeran las IGU disponibles útiles para integrar la infraestructura de autenticación en interfaces personalizadas.

14.5.1. IGU para seleccionar credenciales

Si es necesario seleccionar un Authentication Configuration del conjunto almacenado en la BBDD Autenticación está disponible en la clase IGU QgsAuthConfigSelect.

../../_images/QgsAuthConfigSelect.png

y se puede utilizar como en el siguiente fragmento:

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" )

El ejemplo anterior está tomado de la fuente QGIS code. El segundo parámetro del constructor de GUI se refiere al tipo de proveedor de datos. El parámetro se utiliza para restringir el Método de autenticación compatible con el proveedor especificado.

14.5.2. IGU Editor Autenticación

La GUI completa utilizada para administrar credenciales, autoridades y para acceder a las utilidades de autenticación es administrada por la clase QgsAuthEditorWidgets.

../../_images/QgsAuthEditorWidgets.png

y se puede utilizar como en el siguiente fragmento:

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()

Se puede encontrar un ejemplo integrado en el test.

14.5.3. IGU de Editor de Autoridades

Una GUI utilizada para administrar solo las autoridades es administrada por la clase QgsAuthAuthoritiesEditor.

../../_images/QgsAuthAuthoritiesEditor.png

y se puede utilizar como en el siguiente fragmento:

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()