Remarques :
- Ce tutoriel nécessite un accès à Oracle Cloud. Pour vous inscrire à un compte gratuit, reportez-vous à Introduction au niveau gratuit d'Oracle Cloud Infrastructure.
- Il utilise des exemples de valeur pour les informations d'identification, la location et les compartiments Oracle Cloud Infrastructure. A la fin de l'exercice, remplacez ces valeurs par des valeurs propres à votre environnement cloud.
Suppression d'utilisateurs inactifs des domaines d'identité OCI IAM basés sur UserStatus et LastSuccessfulLoginDate à l'aide de Python
Introduction
Oracle Cloud Infrastructure (OCI) est une plate-forme cloud capable de fournir une gamme de services cloud, y compris le stockage, le réseau et l'infrastructure. Oracle Cloud Infrastructure Identity and Access Management (OCI IAM) est un service qui vous permet de gérer l'accès aux ressources OCI. Il fournit une authentification et une autorisation pour les utilisateurs et les groupes.
La suppression des utilisateurs inactifs en fonction de leur dernière date de connexion réussie dans les domaines d'identité OCI IAM peut s'avérer particulièrement utile dans le contexte du modèle de tarification par utilisateur d'OCI pour plusieurs raisons :
-
Optimisation des coûts : OCI suit un modèle de tarification par utilisateur, ce qui signifie que vous êtes facturé pour chaque compte utilisateur. En identifiant et en supprimant régulièrement les utilisateurs inactifs, vous pouvez réduire considérablement vos coûts d'abonnement. Cette optimisation des coûts devient encore plus critique à mesure que votre entreprise évolue et que le nombre d'utilisateurs augmente.
-
Amélioration de la sécurité : les comptes utilisateur inactifs représentent un risque potentiel pour la sécurité. Ces comptes ne peuvent plus être utilisés par des utilisateurs légitimes, mais ils peuvent toujours être exploités par des acteurs malveillants s'ils sont laissés sans surveillance. La suppression des utilisateurs inactifs garantit que seules les personnes autorisées ont accès à vos ressources OCI, ce qui réduit la surface d'attaque et améliore la sécurité globale.
-
Resource Management : la gestion d'un grand nombre de comptes utilisateur inactifs peut s'avérer fastidieuse sur le plan administratif. Il corrige votre environnement IAM et rend plus difficile de se concentrer sur les comptes utilisateur actifs. L'automatisation du processus d'identification et de suppression des utilisateurs inactifs libère des ressources administratives et permet à votre équipe de se concentrer sur des tâches plus stratégiques.
-
Conformité : les normes de conformité exigent souvent que les entreprises examinent et gèrent régulièrement les comptes utilisateur. La suppression des utilisateurs inactifs peut vous aider à répondre aux exigences de conformité et à démontrer un engagement envers la sécurité et la gouvernance des données.
Pour implémenter ce processus efficacement, sous le fragment de code python peut être utilisé pour automatiser l'identification et la suppression des utilisateurs inactifs en fonction de leur dernière date de connexion réussie et de leur statut actif/inactif. En exécutant régulièrement de tels scripts, vous pouvez maintenir un environnement IAM allégé et sécurisé tout en optimisant vos coûts dans OCI.
Public visé
Professionnels et administrateurs IAM.
Objectif
Supprimez des utilisateurs en fonction du statut utilisateur et de lastSuccessfulLoginDate des domaines d'identité OCI IAM à l'aide de l'API REST avec Python.
Prérequis
-
Abonnement OCI actif.
-
Connaissance d'OCI IAM et de Python.
-
Vous devez connaître l'API REST des domaines d'identité OCI IAM.
-
Utilisateur IAM autorisé à gérer les applications (administrateur de domaine d'identité, administrateur de sécurité ou administrateur d'application).
-
Python 3.x est installé sur votre système.
-
Packages Python
urllib3
,requests
etdatetime
installés.
Tâche 1 : créer une application confidentielle dans les domaines d'identité OCI IAM
Suivez Oracle Identity Cloud Service : premier appel d'API REST pour créer une application confidentielle et extraire l'ID client et la clé secrète client, qui peuvent ensuite être utilisés pour effectuer un appel d'API REST vers OCI IAM afin d'extraire le jeton d'accès et les adresses d'API suivantes.
Tâche 2 : configurer le fichier config.json
Configurez le fichier de configuration sur l'ordinateur local. Le fichier config.json
contient des informations sur l'URL du domaine d'identité, l'ID client et la clé secrète client utilisés pour générer le jeton d'accès.
{
"iamurl" : "https://idcs-###########.identity.oraclecloud.com",
"client_id" : "#######################",
"client_secret" : "#######################"
}
Tâche 3 : obtenir le jeton d'accès
Une fois le fichier config.json
en place, vous devez d'abord générer le jeton d'accès, qui peut être utilisé pour effectuer d'autres appels d'API REST vers les adresses OCI IAM.
Dans le fragment de code ci-dessous, la fonction get_encoded prend l'ID client et la clé secrète client en tant qu'arguments et renvoie la chaîne base64-encoded
. Cette chaîne encodée est également transmise en tant qu'argument à la fonction get_access_token
en tant qu'en-tête d'autorisation afin d'obtenir le jeton d'accès en exécutant une demande POST.
#get base64 encoded
def get_encoded(self,clid, clsecret):
encoded = clid + ":" + clsecret
baseencoded = base64.urlsafe_b64encode(encoded.encode('UTF-8')).decode('ascii')
return baseencoded
#get access token
def get_access_token(self,url, header):
para = "grant_type=client_credentials&scope=urn:opc:idm:__myscopes__"
response = requests.post(url, headers=header, data=para, verify=False)
jsonresp = json.loads(response.content)
access_token = jsonresp.get('access_token')
return access_token
#print access token
def printaccesstoken(self):
obj = IAM()
encodedtoken = obj.get_encoded(clientID, clientSecret)
extra = "/oauth2/v1/token"
headers = {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
'Authorization': 'Basic %s' % encodedtoken, 'Accept': '*/*'}
accesstoken = obj.get_access_token(idcsURL + extra, headers)
return accesstoken
Tâche 4 : gérer un lot d'informations utilisateur (lastSuccessfulLoginDate, userStatus) pour nettoyer les utilisateurs
Nous disposons du jeton d'accès à l'aide duquel nous pouvons effectuer d'autres appels d'API REST vers différentes adresses REST de domaines d'identité OCI IAM. Le fragment de code ci-dessous montre comment nous effectuons une demande GET avec les en-têtes et paramètres nécessaires vers l'adresse /admin/v1/Users
, afin d'extraire le nombre total d'utilisateurs, puis de calculer le nombre d'itérations nécessaires, en fonction du nombre total de résultats et du nombre par demande.
-
La fonction obtient la date en cours au format AAAA-MM-JJ et stocke dans une variable
current_date
, puis itère à travers chaque données utilisateur. -
A chaque itération, il envoie une demande GET avec les paramètres appropriés pour extraire un lot d'informations utilisateur (nom utilisateur, lastSuccessfulLoginDate et actif), puis effectue des vérifications conditionnelles.
-
Le code, basé sur des vérifications conditionnelles définies, ajoute le nom utilisateur et l'ID utilisateur pour tous les utilisateurs correspondants dans les fichiers
username.txt
etuserid.txt
respectivement, et le marque pour suppression. Tout d'abord, il vérifie le statut de l'utilisateur et s'il est False (ce qui signifie inactive), il ajoute l'utilisateur aux fichierstxt
et passe à l'itération suivante de la boucle. Il vérifie ensuite l'état de l'utilisateur et, s'il est défini sur Aucun, il imprime ce que _{user} n'a jamais accédé. Prenez la décision de la supprimer manuellement sur la console et passez à l'itération suivante de la boucle. -
Le script extrait la dernière date de connexion réussie de l'utilisateur, calcule le nombre de jours écoulés depuis la dernière connexion et l'imprime sur la console. Pour tout utilisateur qui ne s'est pas connecté depuis plus de 90 jours, le script vérifie si des rôles d'administrateur spécifiques lui sont associés. Tout utilisateur qui n'est pas connecté depuis 90 jours et qui n'a aucun rôle d'administrateur est identifié et marqué pour suppression.
-
Une fois tous les utilisateurs traités, un ensemble d'ID utilisateur à supprimer est écrit dans un fichier JSON
username.json
. Une demande de suppression en masse est préparée en formatant les données dans un format JSON spécifique. La demande de suppression en masse est ensuite envoyée à l'adresse/admin/v1/Bulk
et un message est imprimé pour indiquer que les utilisateurs identifiés ont été supprimés. -
Après toutes les itérations, la fonction revient à la fonction principale.
Remarque : Une section de code est commentée avec des explications sur les actions futures ou les décisions manuelles, telles que la gestion des utilisateurs qui n'ont jamais accédé au système. Il peut arriver qu'un administrateur n'ait pas accédé à OCI IAM et que vous ne souhaitiez pas les supprimer.
def get_successfullogindate(self): extra = "/admin/v1/Users" obj = IAM() accesstoken = obj.printaccesstoken() headers = {'Authorization': 'Bearer ' + accesstoken} resp = requests.get(idcsURL+extra, headers=headers, verify=False) jsonresp = json.loads(resp.content) totalCount = jsonresp.get("totalResults") print("Total number of users: " + str(totalCount)) current_date = datetime.now().date() startIndex = 1 count = 50 loop = int(totalCount / count) extra2 = "/admin/v1/AppRoles" for i in range(loop + 1): param = { 'attributes': "username,active,urn:ietf:params:scim:schemas:oracle:idcs:extension:userState:User:lastSuccessfulLoginDate", 'startIndex': startIndex, 'count': count} resp = requests.get(idcsURL+extra, headers=headers, verify=False, params=param) startIndex += count jsonresp = json.loads(resp.content) tempjsn = jsonresp.get("Resources") for x in tempjsn: trimjsn = {} username = trimjsn['userName'] = x.get("userName") userid = x.get("id") userStatus = x.get("active") userState = x.get("urn:ietf:params:scim:schemas:oracle:idcs:extension:userState:User") if userStatus is False: print(username + " is in inactive state. Will be deleted.") with open('username.txt', 'a') as c: c.write(username) c.write('\n') with open('userID.txt', 'a') as d: d.write(userid) d.write('\n') continue if userState is None: print(username + " has never accessed. Kindly make a decision to delete it manually on console") # with open('username.txt', 'a') as c: # c.write(username) # c.write('\n') # with open('userID.txt', 'a') as d: # d.write(userid) # d.write('\n') # ** Uncomment the lines commented above to delete the users who have never accessed ** continue lastLoginDate = x['urn:ietf:params:scim:schemas:oracle:idcs:extension:userState:User']['lastSuccessfulLoginDate'] target_dates = datetime.strptime(lastLoginDate, '%Y-%m-%dT%H:%M:%S.%fZ').date() num_days = (current_date - target_dates).days #print(username + " Last logged in " + str(num_days) + " days ago") if num_days > 30: #print("entered if condition for more than 90 days ") params2 = {"filter": f'members[value eq "{userid}"] and app.value eq "IDCSAppId" and (displayName eq "Identity Domain Administrator" or displayName eq "Security Administrator" or displayName eq "Application Administrator" or displayName eq "User Administrator" or displayName eq "User Manager" or displayName eq "Help Desk Administrator" or displayName eq "Audit Administrator")'} resp2 = requests.get(idcsURL+extra2, headers=headers, verify=False, params=params2) jsonresp3 = json.loads(resp2.content) totalCount1 = jsonresp3.get("totalResults") if totalCount1 < 1: print(username + " has not Logged in for 90 days and has NO admin role. Will be deleted.") with open('username.txt', 'a') as c: c.write(username) c.write('\n') with open('userID.txt', 'a') as d: d.write(userid) d.write('\n') try: with open('userID.txt','r') as g: lines = len(g.readlines()) except FileNotFoundError: print("No users found to be Deleted by the Script") exit() x=0 while x<lines: with open('userID.txt','r') as e: content = e.readlines() id=content[x] id=id.rstrip(id[-1]) paradelete=json.dumps( { "method": "DELETE", "path": "/Users/"+id+"?forceDelete=true" } ) with open('username.json', 'a') as j: j.writelines(paradelete) j.write(',') x=x+1 with open('username.json', 'r') as file: data = file.read() with open('formatedData.json', 'a') as file1: file1.writelines('{ \n') file1.writelines('"schemas": ["urn:ietf:params:scim:api:messages:2.0:BulkRequest"],\n') file1.writelines('"Operations": [\n') data2=data.rstrip(data[-1]) file1.write(data2) file1.write(']}') headers = {'Authorization': 'Bearer ' + accesstoken} bulkdata = json.load(open('formatedData.json')) param = {'forceDelete': True} payload = json.dumps(bulkdata) headers2 = {'Content-Type': 'application/json','Authorization': 'Bearer ' + accesstoken, 'Accept': '*/*'} extra2="/admin/v1/Bulk" #respdelete = requests.request("POST",idcsURL + extra2, headers=headers2, verify=False, params=param,data=payload) print("The identified users has been deleted ") try: os.remove('userID.txt') os.remove('username.txt') os.remove('formatedData.json') os.remove('username.json') except FileNotFoundError: exit()
Tâche 5 : utiliser le script dans OCI Cloud Shell
Une fois le script prêt, il peut être facilement exécuté sur la machine locale (avec Python installé) ou sur n'importe quel IDE prenant en charge le développement Python. Nous utilisons OCI Cloud Shell pour exécuter le script et obtenir le rapport souhaité.
-
Connectez-vous à la console OCI, ouvrez Cloud Shell dans l'angle supérieur droit de l'écran, puis téléchargez le script Python et le fichier
config.json
. -
Exécutez
python DeleteUser_PriorCheck_InactivePeriod60days_IsAdmin.py
.Remarque :
DeleteUser_PriorCheck_InactivePeriod60days_IsAdmin.py
est le script Python développé à l'aide des fragments de code ci-dessus.
Liens connexes
Remerciements
-
Auteur - Gautam Mishra (ingénieur cloud senior)
-
Contributeur - Chetan Soni (ingénieur solutions cloud)
Ressources de formation supplémentaires
Parcourez d'autres ateliers sur docs.oracle.com/learn ou accédez à davantage de contenus de formation gratuits sur le canal Oracle Learning YouTube. De plus, rendez-vous sur education.oracle.com/learning-explorer pour devenir un explorateur Oracle Learning.
Pour obtenir de la documentation sur le produit, visitez Oracle Help Center.
Delete Inactive Users from OCI IAM Identity Domains Based on UserStatus and LastSuccessfulLoginDate Using Python
F89514-01
November 2023
Copyright © 2023, Oracle and/or its affiliates.