Search code examples
oauth-2.0permissionsmicrosoft-graph-apimicrosoft-teams

Microsoft Graph Delegated permissions show all tenants data


I want to build an app that lists the teams that the current user is member of in Microsoft Teams using the Microsoft Graph API and the user should only be able to see her own teams.

The problem is that the app gets access to ALL teams on the tenant and not only the teams that the user already belongs to.

This is an issue because even just the naming of a private team can be confidential information in some organizations.

According to the documentation (https://learn.microsoft.com/en-us/graph/api/group-list?view=graph-rest-1.0&tabs=http) the least privileged permission for listing Groups is “GroupMember.Read.All”.

I therefore create an app with this permission and the type is “Delegated”.

App delegated permissions

Since the permission requires admin consent I manually give admin consent to the app in the AAD Portal.

I now ask the user to authorize the app on her behalf by having her follow this link:

`https://login.microsoftonline.com/[tenant]/
oauth2/v2.0/authorize?client_id=[clientId]
&redirect_uri=[redirectUri]
&response_type=code
&response_mode=query
&prompt=consent
&scope=https%3A%2F%2Fgraph.microsoft.com%2Fuser.read offline_access`

Through the OAUTH2 flow the server obtains an access token for the user and the delegated permissions. The access token is used to call the Graph API mentioned before:

https://graph.microsoft.com/v1.0/groups?$filter=resourceProvisioningOptions/Any(x:x eq 'Team')

The issue is that the request returns ALL teams on the tenant and not only the teams that the user has access to in MS Teams client - including a long list of private teams that the user should not be able to see at all.

How can it be that the access token obtained from the user approving the app gives the app access to all teams and not just the teams that the user is member of?


Solution

  • There are two endpoints that can be useful for you

    First endpoint

    GET /me/joinedTeams
    

    gets the teams that the user is a direct member of.

    The second one

    GET /users/{user-id}/teamwork/associatedTeams
    

    gets the list of teams that the user is a direct member of a team or is a member of a shared channel that is hosted inside a team.

    Documentation:

    List joined teams

    List associated teams info