14. Infrastruttura di autenticazione
Suggerimento
I frammenti di codice di questa pagina necessitano delle seguenti importazioni se sei è al di fuori della console 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. Introduzione
Riferimenti per l’utente all’infrastruttura di autenticazione possono essere letti nel Manuale dell’utente nel paragrafo Panoramica sul sistema di autenticazione.
Questo capitolo descrive le migliori pratiche per utilizzare il sistema di autenticazione dal punto di vista dello sviluppatore.
Il sistema di autenticazione è ampiamente utilizzato in QGIS Desktop dai fornitori di dati ogni volta che sono richieste le credenziali per accedere a una particolare risorsa, ad esempio quando un layer stabilisce una connessione a un database Postgres.
Nella libreria QGIS gui sono presenti anche alcuni widget che gli sviluppatori di plugin possono utilizzare per integrare facilmente l’infrastruttura di autenticazione nel proprio codice:
Un buon riferimento per il codice può essere letto nell” infrastruttura di autenticazione tests code.
Avvertimento
A causa dei vincoli di sicurezza presi in considerazione durante la progettazione dell’infrastruttura di autenticazione, solo un sottoinsieme selezionato dei metodi interni è aperto a Python.
14.2. Glossario
Ecco qualche definizione degli oggetti più comuni trattati in questo capitolo.
- Master Password
Password che permette l’accesso e la decriptazione delle credenziali memorizzate nel DB di autenticazione di QGIS.
- Database di autenticazione
Una Master Password criptato sqlite db
qgis-auth.db
in cui Authentication Configuration sono memorizzati. ad esempio utente/password, certificati e chiavi personali, autorità di certificazione.- Autenticazione DB
- Configurazione autenticazione
Un insieme di dati di autenticazione che dipende da Authentication Method. Ad esempio, il metodo di autenticazione di base memorizza la coppia utente/password.
- Authentication Config
- Authentication Method
Un metodo specifico utilizzato per ottenere l’autenticazione. Ogni metodo ha un proprio protocollo utilizzato per ottenere il livello di autenticazione. Ogni metodo è implementato come libreria condivisa caricata dinamicamente durante l’avvio dell’infrastruttura di autenticazione di QGIS.
14.3. QgsAuthManager il punto di ingresso
Il singleton QgsAuthManager
è il punto di ingresso per utilizzare le credenziali memorizzate nel Authentication DB criptato di QGIS, ovvero il file qgis-auth.db
sotto la cartella attiva user profile.
Questa classe si occupa dell’interazione con l’utente: chiedendo di impostare una master password o utilizzandola in modo trasparente per accedere alle informazioni crittografate memorizzate.
14.3.1. Avviare il manager e impostare la master password
Il seguente frammento di codice fornisce un esempio di impostazione della master password per aprire l’accesso alle impostazioni di autenticazione. I commenti al codice sono importanti per la comprensione del codice.
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. Popolare authdb con una nuova voce di configurazione dell’autenticazione
Ogni credenziale memorizzata è un’istanza Authentication Configuration della classe QgsAuthMethodConfig
a cui si accede utilizzando una stringa univoca come la seguente:
authcfg = 'fm1s770'
Questa stringa viene generata automaticamente quando si crea una voce utilizzando l’API o la GUI di QGIS, ma potrebbe essere utile impostarla manualmente su un valore noto nel caso in cui la configurazione debba essere condivisa (con credenziali diverse) tra più utenti all’interno di un’organizzazione.
QgsAuthMethodConfig
è la classe base per qualsiasi Authentication Method. Ogni metodo di autenticazione imposta una mappa hash di configurazione in cui saranno memorizzate le informazioni di autenticazione. Di seguito un utile frammento di codice per memorizzare le credenziali del percorso PKI per un ipotetico utente 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. Metodi di autenticazione disponibili
Le librerie Authentication Method sono caricate dinamicamente durante l’avvio del gestore di autenticazione. I metodi di autenticazione disponibili sono:
Basic
Autenticazione utente e passwordEsriToken
Autenticazione basata su token ESRIIdentity-Cert
Identificazione certificato autenticazioneOAuth2
autenticazione OAuth2PKI-Paths
Autenticazione percorsi PKIPKI-PKCS#12
Autenticazione PKI PKCS#12
14.3.2.3. Gestire i pacchetti PKI con QgsPkiBundle
Una classe di comodo per confezionare pacchetti PKI composti da SslCert, SslKey e catena di CA è la classe QgsPkiBundle
. Di seguito uno frammento di codice per ottenere una password protetta:
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()
Fare riferimento alla documentazione della classe QgsPkiBundle
per estrarre cert/key/CA dal pacchetto.
14.3.3. Rimuovere una voce da authdb
Possiamo rimuovere una voce da Authentication Database usando il suo identificatore authcfg
con il seguente frammento di codice:
authMgr = QgsApplication.authManager()
authMgr.removeAuthenticationConfig( "authCfg_Id_to_remove" )
14.3.4. Lasciare l’espansione di authcfg a QgsAuthManager
Il modo migliore per utilizzare una Authentication Config memorizzata nel Authentication DB è riferirla con l’identificatore unico authcfg
. Espandere significa convertire l’identificatore in un insieme completo di credenziali. La pratica migliore per utilizzare le Authentication Config` memorizzate è quella di lasciarle gestire automaticamente dal gestore dell’autenticazione. L’uso comune di una configurazione memorizzata è quello di connettersi a un servizio abilitato all’autenticazione, come un WMS o un WFS, o a una connessione DB.
Nota
Tenere presente che non tutti i fornitori di dati QGIS sono integrati con l’infrastruttura di autenticazione. Ogni metodo di autenticazione, derivato dalla classe base QgsAuthMethod
, supporta un diverso insieme di provider. Ad esempio, il metodo certIdentity()
supporta il seguente elenco di provider:
authM = QgsApplication.authManager()
print(authM.authMethod("Identity-Cert").supportedDataProviders())
Esempio di output:
['ows', 'wfs', 'wcs', 'wms', 'postgres']
Ad esempio, per accedere a un servizio WMS utilizzando le credenziali memorizzate identificate con authcfg = 'fm1s770'
, è sufficiente utilizzare authcfg
nell’URL dell’origine dati, come nel seguente frammento di codice:
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')
Nel caso di cui sopra, il provider wms
avrà cura di espandere il parametro URI authcfg
con le credenziali appena prima di impostare la connessione HTTP.
Avvertimento
Lo sviluppatore dovrebbe lasciare l’espansione di ``authcfg”” alla QgsAuthManager
, in questo modo sarà sicuro che l’espansione non venga fatta troppo presto.
Di solito una stringa URI, costruita usando la classe QgsDataSourceURI
, viene usata per impostare un’origine dati nel modo seguente:
authCfg = 'fm1s770'
quri = QgsDataSourceUri("my WMS uri here")
quri.setParam("authcfg", authCfg)
rlayer = QgsRasterLayer( quri.uri(False), 'states', 'wms')
Nota
Il parametro False
è importante per evitare l’espansione completa dell’URI dell’id authcfg
presente nell’URI.
14.3.4.1. Esempi di PKI con altri fornitori di dati
Altri esempi possono essere letti direttamente nei test di QGIS a monte, come in test_authmanager_pki_ows o test_authmanager_pki_postgres.
14.4. Adattare i plugin per utilizzare l’infrastruttura di autenticazione
Molti plugin di terze parti utilizzano httplib2 o altre librerie di rete Python per gestire le connessioni HTTP, invece di integrarsi con QgsNetworkAccessManager
e la relativa integrazione dell’infrastruttura di autenticazione.
Per facilitare questa integrazione è stata creata una funzione helper in Python chiamata NetworkAccessManager
. Il suo codice si trova here.
Questa helper classe può essere utilizzata come nel seguente frammento di codice:
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. GUI di autenticazione
In questo paragrafo sono elencate le GUI disponibili utili per integrare l’infrastruttura di autenticazione in interfacce personalizzate.
14.5.1. GUI per selezionare le credenziali
Se è necessario selezionare una Authentication Configuration dall’insieme memorizzato nel Authentication DB, è disponibile nella classe GUI QgsAuthConfigSelect
.
e può essere utilizzato come nel seguente frammento di codice:
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" )
L’esempio precedente è tratto dal sorgente QGIS code. Il secondo parametro del costruttore GUI si riferisce al tipo di fornitore di dati. Il parametro viene utilizzato per limitare i Authentication Method compatibili con il provider specificato.
14.5.2. Editor autenticazione GUI
L’interfaccia grafica completa utilizzata per gestire le credenziali, le autorità e per accedere alle utilità di autenticazione è gestita dalla classe QgsAuthEditorWidgets
.
e può essere utilizzato come nel seguente frammento di codice:
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()
Un esempio integrato si trova nel relativo test.