Gruppenmitgliedschaften abfragen
In diesem Leitfaden wird gezeigt, wie Sie eine Gruppenmitgliedschaft transitiv abfragen und das Mitgliedsdiagramm eines Mitglieds abrufen können.
Zusätzlich zur Auflistung der direkten Mitglieder einer Gruppe können Sie auch transitiv sowohl direkte als auch indirekte Mitgliedschaften suchen und sich das Mitgliedschaftsdiagramm eines bestimmten Mitglieds anzeigen lassen. Diese Funktionen sind für folgende Anwendungsfälle relevant:
- Ressourceninhaber können fundierte Entscheidungen über Änderungen an Ressourcen-ACLs treffen, wenn sie verstehen, welche Gruppen und Mitglieder von Änderungen betroffen sind.
- Gruppeninhaber können die Auswirkungen des Hinzufügens oder Entfernens einer Gruppe zu/von einer Gruppe mit ACL-Kontrolle besser bewerten und Mitgliedschaftsprobleme einfacher lösen.
- Sicherheitsprüfer können Zugriffsrichtlinien effektiver prüfen, da die erweiterte Mitgliedschaftsstruktur ihrer gesamten Organisation sichtbar ist.
- Sicherheitsprüfer können das Sicherheitsrisiko eines Mitglieds bewerten. Dazu müssen sie sich ihre direkten und indirekten Gruppenmitgliedschaften ansehen oder prüfen, ob ein Mitglied zu einer bestimmten Gruppe gehört.
Eine Gruppenmitgliedschaft kann zu einer Einzelperson, einem Dienstkonto oder einer anderen Gruppe gehören.
Das Nutzer- oder Dienstkonto, von dem die Abfrage stammt, muss die Berechtigung zum Anzeigen der Mitgliedschaften aller Gruppen haben, die Teil der Abfrage sind. Andernfalls schlägt die Anfrage fehl. Wenn die Abfrage den Fehler „PERMISSION_DENIED” zurückgibt, haben Sie wahrscheinlich nicht die richtigen Berechtigungen für eine der verschachtelten Gruppen, insbesondere wenn eine dieser Gruppen zu einer anderen Organisation gehört.
Hinweise
Enable the Cloud Identity API.
Nach allen Mitgliedschaften in einer Gruppe suchen
Dieser Code gibt alle Mitgliedschaften einer Gruppe zurück. Die Antwort enthält für jede Mitgliedschaft den Typ der Mitgliedschaft (direkt, indirekt oder beides).
REST
Rufen Sie groups.memberships.searchTransitiveMemberships()
mit der ID der übergeordneten Gruppe auf, um eine Liste aller Mitgliedschaften in einer Gruppe abzurufen.
Python
Richten Sie die Standardanmeldedaten für Anwendungen ein, um sich bei Cloud Identity zu authentifizieren. Weitere Informationen finden Sie unter Authentifizierung für eine lokale Entwicklungsumgebung einrichten.
import googleapiclient.discovery
from urllib.parse import urlencode
def search_transitive_memberships(service, parent, page_size):
try:
memberships = []
next_page_token = ''
while True:
query_params = urlencode(
{
"page_size": page_size,
"page_token": next_page_token
}
)
request = service.groups().memberships().searchTransitiveMemberships(parent=parent)
request.uri += "&" + query_params
response = request.execute()
if 'memberships' in response:
memberships += response['memberships']
if 'nextPageToken' in response:
next_page_token = response['nextPageToken']
else:
next_page_token = ''
if len(next_page_token) == 0:
break;
print(memberships)
except Exception as e:
print(e)
def main():
service = googleapiclient.discovery.build('cloudidentity', 'v1')
# Return results with a page size of 50
search_transitive_memberships(service, 'groups/GROUP_ID', 50)
if __name__ == '__main__':
main()
Nach allen Gruppenmitgliedschaften eines Mitglieds suchen
REST
Um alle Gruppen zu finden, zu denen ein Mitglied gehört, rufen Sie groups.memberships.searchTransitiveGroups()
mit dem Mitgliedsschlüssel auf (z. B. die E-Mail-Adresse des Mitglieds).
Python
Richten Sie die Standardanmeldedaten für Anwendungen ein, um sich bei Cloud Identity zu authentifizieren. Weitere Informationen finden Sie unter Authentifizierung für eine lokale Entwicklungsumgebung einrichten.
Dieser Code gibt alle Gruppen zurück, zu denen ein Mitglied gehört (mit Ausnahme von Gruppen mit Identitätszuweisung), sowohl direkt als auch indirekt.
import googleapiclient.discovery
from urllib.parse import urlencode
def search_transitive_groups(service, member, page_size):
try:
groups = []
next_page_token = ''
while True:
query_params = urlencode(
{
"query": "member_key_id == '{}' && 'cloudidentity.googleapis.com/groups.discussion_forum' in labels".format(member),
"page_size": page_size,
"page_token": next_page_token
}
)
request = service.groups().memberships().searchTransitiveGroups(parent='groups/-')
request.uri += "&" + query_params
response = request.execute()
if 'memberships' in response:
groups += response['memberships']
if 'nextPageToken' in response:
next_page_token = response['nextPageToken']
else:
next_page_token = ''
if len(next_page_token) == 0:
break;
print(groups)
except Exception as e:
print(e)
def main():
service = googleapiclient.discovery.build('cloudidentity', 'v1')
# Return results with a page size of 50
search_transitive_groups(service, 'MEMBER_EMAIL_ADDRESS', 50)
if __name__ == '__main__':
main()
Mitgliedschaft in einer Gruppe prüfen
REST
Um zu überprüfen, ob ein Mitglied zu einer bestimmten Gruppe gehört (entweder direkt oder
indirekt), rufen Sie
checkTransitiveMembership()
durch die ID der übergeordneten Gruppe und den Mitgliedsschlüssel (z. B. die E-Mail-Adresse
Adresse des Mitglieds).
Python
Richten Sie die Standardanmeldedaten für Anwendungen ein, um sich bei Cloud Identity zu authentifizieren. Weitere Informationen finden Sie unter Authentifizierung für eine lokale Entwicklungsumgebung einrichten.
Folgender Code bestimmt, ob das Mitglied zu einer bestimmten Gruppe gehört:
import googleapiclient.discovery
from urllib.parse import urlencode
def check_transitive_membership(service, parent, member):
try:
query_params = urlencode(
{
"query": "member_key_id == '{}'".format(member)
}
)
request = service.groups().memberships().checkTransitiveMembership(parent=parent)
request.uri += "&" + query_params
response = request.execute()
print(response['hasMembership'])
except Exception as e:
print(e)
def main():
service = googleapiclient.discovery.build('cloudidentity', 'v1')
check_transitive_membership(service, 'groups/GROUP_ID', 'MEMBER_EMAIL_ADDRESS')
if __name__ == '__main__':
main()
Mitgliedschaftsdiagramm für ein Mitglied abrufen
REST
Rufen Sie groups.memberships.getMembershipGraph()
mit der ID die übergeordnete Gruppe und den Mitgliedsschlüssel (z. B. die E-Mail-Adresse des Mitglieds) auf, um das Mitgliedschaftsdiagramm (alle Gruppen, zu denen ein Mitglied gehört, zusammen mit den Pfadinformationen) eines Mitglieds zu erhalten. Das Diagramm wird als Adjazenzliste zurückgegeben.
Python
Richten Sie Standardanmeldedaten für Anwendungen ein, um sich bei Cloud Identity zu authentifizieren. Weitere Informationen finden Sie unter Authentifizierung für eine lokale Entwicklungsumgebung einrichten.
Der folgende Code gibt das Mitgliedschaftsdiagramm eines angegebenen Mitglieds in einer Google-Gruppe zurück (diese Abfrage wird unter Verwendung des Labels nach Gruppentyp gefiltert):
import googleapiclient.discovery
from urllib.parse import urlencode
def get_membership_graph(service, parent, member):
try:
query_params = urlencode(
{
"query": "member_key_id == '{}' && 'cloudidentity.googleapis.com/groups.discussion_forum' in labels".format(member)
}
)
request = service.groups().memberships().getMembershipGraph(parent=parent)
request.uri += "&" + query_params
response = request.execute()
print(response['response'])
except Exception as e:
print(e)
def main()
service = googleapiclient.discovery.build('cloudidentity', 'v1')
# Specify parent group as 'groups/-' to get ALL the groups of a member
# along with path information
get_membership_graph(service, 'groups/GROUP_ID', 'MEMBER_KEY')
if __name__ == '__main__':
main()
Eine visuelle Darstellung des Mitgliedsdiagramms erstellen
Das folgende Beispiel zeigt eine Antwort vom Python-Code oben. In diesem Beispiel sind die Gruppen 000, 111 und 222 so verbunden (Pfeile sind vom übergeordneten zum untergeordneten Element): 000 -> 111 -> 222. Ein Aufruf des Beispielcodes zum Abrufen der vollständigen Grafik für Gruppe 222:
get_membership_graph(service, 'groups/-', 'group-2@example.com')
führt zur folgenden Antwort:
{
"@type": "type.googleapis.com/google.apps.cloudidentity.groups.v1.GetMembershipGraphResponse",
"adjacencyList": [
{
"edges": [
{
"name": "groups/000/memberships/111",
"preferredMemberKey": {
"id": "group-1@example.com"
},
"roles": [
{
"name": "MEMBER"
}
]
}
],
"group": "groups/000"
},
{
"edges": [
{
"name": "groups/111/memberships/222",
"preferredMemberKey": {
"id": "group-2@example.com"
},
"roles": [
{
"name": "MEMBER"
}
]
}
],
"group": "groups/111"
}
],
"groups": [
{
"name": "groups/000",
"groupKey": {
"id": "group-0@example.com"
},
"displayName": "Group - 0",
"description": "Group - 0",
"labels": {
"cloudidentity.googleapis.com/groups.discussion_forum": ""
}
},
{
"name": "groups/111",
"groupKey": {
"id": "group-1@example.com"
},
"displayName": "Group - 1",
"description": "Group - 1",
"labels": {
"cloudidentity.googleapis.com/groups.discussion_forum": ""
}
},
{
"name": "groups/222",
"groupKey": {
"id": "group-2@example.com"
},
"displayName": "Group - 2",
"description": "Group - 2",
"labels": {
"cloudidentity.googleapis.com/groups.discussion_forum": ""
}
}
]
}
Jedes Element in der Adjazenz-Liste stellt eine Gruppe und deren direkte Mitglieder (Edges) dar. Die Antwort enthält auch Details zu allen Gruppen im Mitgliedschaftsdiagramm. Sie kann geparst werden, um alternative Darstellungen (z. B. ein DOT-Diagramm) zu generieren, die zur Visualisierung des Mitgliedsdiagramms dienen können.
Dieses Beispielskript kann verwendet werden, um die Antwort in eine DOT-Grafik zu konvertieren:
#
# Generates output in a dot format. Invoke this method using
# response['response'] from get_membership_graph()
#
# Save the output to a .dot file (say graph.dot)
# Use the dot tool to generate a visualization of the graph
# Example:
# dot -Tpng -o graph.png graph.dot
#
# Generates output like below:
#
# digraph {
# 'group0' [label='groups/000 (GROUP 0)'];
# 'group1' [label='groups/111 (GROUP 1)'];
# 'group2' [label='groups/222 (GROUP 2)'];
# 'group3' [label='groups/333 (GROUP 3)'];
# 'group4' [label='groups/444 (GROUP 4)'];
#
# 'group0' -> 'group1' [label='[email protected] (MEMBER)'];
# 'group0' -> 'group2' [label='[email protected] (MEMBER)'];
# 'group1' -> 'group3' [label='[email protected] (MEMBER)'];
# 'group3' -> 'group4' [label='[email protected] (MEMBER)'];
# 'group2' -> 'group3' [label='[email protected] (MEMBER)'];
# }
#
def convert_to_dot_format(graph):
output = "digraph {\n"
try:
# Generate labels for the group nodes
for group in graph['groups']:
if 'displayName' in group:
label = '{} ({})'.format(group['name'], group['displayName'])
else:
label = group['name']
output += ' "{}" [label="{}"];\n'.format(group['name'].split('/')[1], label)
output += '\n'
# Generate edges
for item in graph['adjacencyList']:
group_id = item['group'].split('/')[1]
for edge in item['edges']:
edge_to = edge['name'].split('/')[3]
edge_key = edge['preferredMemberKey']['id']
# Collect the roles
roles = []
for role in edge['roles']:
roles.append(role['name'])
output += ' "{}" -> "{}" [label="{} ({})"];\n'.format(group_id,
edge_to,
edge_key,
','.join(roles))
output += "}\n"
print(output)
except Exception as e:
print(e)
Im Folgenden ist die resultierende visuelle Hierarchie der Beispielantwort dargestellt: