Documentation en ligne

Approvisionner et déprovisionner les utilisateurs depuis authentic

Authentic peut être utilisé comme référentiel des utilisateurs et servir à approvisionner et à dé-provisionner des applications tierces.

Les applications interrogent authentic pour ces opérations. Authentic ne fait pas de notification des évènements sur les utilisateurs aux applications.

 

S'il n'est pas possible d'intégrer cela directement dans une application, une application en charge d'interroger authentic et de répercuter les changements dans la base utilisateur de l'application cible est à développer.

 

Approvisionnement

Pour l'approvisionnement, un script est à développer pour consulter les utilisateurs d'authentic en utilisant le WebService /api/users/ et ensuite apporter les modifications dans la base utilisateurs de l'application cible.

Ce script est à exécuter à intervalle régulier. La durée de l'intervalle dépend du besoin de synchronisation des comptes.

Afin de ne lister que les utilisateurs créés et modifiés le paramètre modified__gt doit être passé en paramètre de la requête de lecture avec pour valeur la date de dernière syncrhonisation.

Dé-provisionnement

Pour dé-provisionner, un script est à développer pour consulter les utilisateurs d'authentic qui n'existent plus en utilisant le WebService de « Tests d'existence des comptes en masse » /api/users/synchronization/ et ensuite apporter les modifications dans la base utilisateurs de l'application cible (suppression, désactivation, archivage, etc.).

Ce script est à exécuter à intervalle régulier. La durée de l'intervalle dépend du besoin de synchronisation des comptes.

Exemple de script

Ci-dessous un exemple de script réalisant un approvisionnement et un dé-provisionnement depuis authentic sur un autre autentic.

# authentic2 - Authentic2 synchronization script example
# Copyright (C) 2017-2018  Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see .

import datetime
import requests
import sys

import django.db
from django.conf import settings
from django.contrib.auth import get_user_model
from django.core.management.base import BaseCommand

from authentic2_auth_oidc.models import OIDCProvider, OIDCAccount


class Command(BaseCommand):
    def handle(self, *args, **options):
        User = get_user_model()

        verbose = int(options['verbosity']) > 0

        a2_provider = OIDCProvider.objects.get(slug='a2_source')
        auth = (a2_provider.client_id, a2_provider.client_secret)

        # check all existing users
        def chunks(l, n):
            for i in range(0, len(l), n):
                yield l[i:i + n]

        url = settings.A2_SOURCE_API_BASE_URL + 'users/synchronization/'
        unknown_uuids = []
        for accounts in chunks(OIDCAccount.objects.filter(provider=a2_provider), 100):
            subs = [x.sub for x in accounts]
            resp = requests.post(url, json={'known_uuids': subs}, auth=auth)
            unknown_uuids.extend(resp.json().get('unknown_uuids'))

        User.objects.filter(oidc_account__sub__in=unknown_uuids).delete()

        # update recently modified users
        url = settings.A2_SOURCE_API_BASE_URL + 'users/?modified__gt=%s' % (
                datetime.datetime.now() - datetime.timedelta(seconds=120)).strftime('%Y-%m-%dT%H:%M:%S')
        resp = requests.get(url, auth=auth)
        for user_dict in resp.json()['results']:
            try:
                user = User.objects.get(email=user_dict['email'])
            except User.DoesNotExist:
                continue
            for claim in a2_provider.claim_mappings.all():
                setattr(user, claim.attribute, user_dict.get(claim.claim))
                try:
                    setattr(user.attributes, claim.attribute, user_dict.get(claim.claim))
                except AttributeError:
                    pass
            user.save()

Dernière mise à jour le 9 août 2023 21:16 — Éditer