Home

Validating a user's membership of a Team - Context object

%3CLINGO-SUB%20id%3D%22lingo-sub-842175%22%20slang%3D%22en-US%22%3EValidating%20a%20user's%20membership%20of%20a%20Team%20-%20Context%20object%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-842175%22%20slang%3D%22en-US%22%3E%3CP%3EWe%20should%20use%20the%20values%20from%20the%26nbsp%3B%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fjavascript%2Fapi%2F%40microsoft%2Fteams-js%2Fmicrosoftteams.context%3Fview%3Dmsteams-client-js-latest%22%20target%3D%22_self%22%20rel%3D%22noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3EContext%20object%3C%2FA%3Ewith%20due%20care%2C%20as%20someone%20might%20be%20running%20our%20app%20in%20a%20rogue%20environment%2C%20injecting%20values%20to%20manipulate%20the%20outcome.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EFor%20the%20user's%20login%2C%20I%20understand%20that%20we%20use%20it%20as%20a%20login%20hint%20and%20the%20authentication%20flow%20will%20always%20end%20in%20an%20interactive%20logon%20screen%20if%20that%20login%20hint%20is%20unknown.%20So%20we%20are%20pretty%20safe%20there.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EBut%20what%20about%20the%20organisationId%20%2F%20teamId%20if%20you%20have%20created%20a%20Team%20tab.%20How%20can%20we%20check%20whether%20that%20user%20is%20actually%20part%20of%20that%20team%2C%20if%20we%20only%20have%20user-delegated%20access%3F%20If%20we%20want%20to%20consult%20the%20%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fgraph%2Fapi%2Fuser-list-joinedteams%3Fview%3Dgraph-rest-1.0%26amp%3Btabs%3Dhttp%22%20target%3D%22_self%22%20rel%3D%22noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3Eme%2FjoinedTeams%3C%2FA%3Eor%20%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fgraph%2Fapi%2Fgroup-list%3Fview%3Dgraph-rest-1.0%26amp%3Btabs%3Dhttp%22%20target%3D%22_self%22%20rel%3D%22noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3EGroups%3C%2FA%3Eendpoints%20of%20Microsoft%20Graph%2C%20we%20need%20admin-level%20consent%20(only%20permissions%20ending%20in%20%22.All%22%20can%20do%20this%20query).%20I%20really%20want%20to%20avoid%20needing%20admin%20consent%20(for%20obvious%20reasons).%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-LABS%20id%3D%22lingo-labs-842175%22%20slang%3D%22en-US%22%3E%3CLINGO-LABEL%3Egraph%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3EMicrosoft%20Teams%3C%2FLINGO-LABEL%3E%3C%2FLINGO-LABS%3E%3CLINGO-SUB%20id%3D%22lingo-sub-843846%22%20slang%3D%22en-US%22%3ERe%3A%20Validating%20a%20user's%20membership%20of%20a%20Team%20-%20Context%20object%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-843846%22%20slang%3D%22en-US%22%3E%3CP%3E%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F405102%22%20target%3D%22_blank%22%3E%40salvijansen%3C%2FA%3E%2C%20Thanks%20for%20reaching%20us.%20FYI%2C%3C%2FP%3E%0A%3CP%3ESome%20high-privilege%20permissions%20in%20the%20Microsoft%20ecosystem%20can%20be%20set%20to%20%3CEM%3Eadmin-restricted%3C%2FEM%3E.%20Examples%20of%20these%20kinds%20of%20permissions%20include%20the%20following%3A%3C%2FP%3E%0A%3CUL%3E%0A%3CLI%3ERead%20all%20user's%20full%20profiles%20by%20using%3CCODE%3EUser.Read.All%3C%2FCODE%3E%3C%2FLI%3E%0A%3CLI%3EWrite%20data%20to%20an%20organization's%20directory%20by%20using%26nbsp%3B%3CCODE%3EDirectory.ReadWrite.All%3C%2FCODE%3E%3C%2FLI%3E%0A%3CLI%3ERead%20all%20groups%20in%20an%20organization's%20directory%20by%20using%20%3CCODE%3E%3C%2FCODE%3E%3CCODE%3EGroups.Read.All%3C%2FCODE%3E%3C%2FLI%3E%0A%3CLI%3EAlthough%20a%20consumer%20user%20might%20grant%20an%20application%20access%20to%20this%20kind%20of%20data%2C%20organizational%20users%20are%20restricted%20from%20granting%20access%20to%20the%20same%20set%20of%20sensitive%20company%20data.%20If%20your%20application%20requests%20access%20to%20one%20of%20these%20permissions%20from%20an%20organizational%20user%2C%20the%20user%20receives%20an%20error%20message%20that%20says%20they're%20not%20authorized%20to%20consent%20to%20your%20app's%20permissions%3CCODE%3E%3C%2FCODE%3E%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3CP%3E%3CCODE%3E%3C%2FCODE%3EFor%20more%20information%20please%20have%20a%20look%20at%20documentation%20for%20%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Factive-directory%2Fdevelop%2Fv2-permissions-and-consent%23admin-restricted-permissions%22%20target%3D%22_self%22%20rel%3D%22noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3EAdmin%20Restricted%20Permissions.%3C%2FA%3E%3CCODE%3E%3C%2FCODE%3E%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-844577%22%20slang%3D%22en-US%22%3ERe%3A%20Validating%20a%20user's%20membership%20of%20a%20Team%20-%20Context%20object%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-844577%22%20slang%3D%22en-US%22%3E%3CP%3E%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F371090%22%20target%3D%22_blank%22%3E%40Trinetra-MSFT%3C%2FA%3E%26nbsp%3BHi%20Trinetra%2C%20thank%20you%20for%20your%20reply!%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EI%20know%20the%20reasoning%20behind%20the%20admin-level%20permissions%2C%20but%20at%20the%20moment%20I'm%20not%20able%20to%20check%20the%20team%20id%20I%20get%20from%20the%20Context%20object.%20When%20launched%20as%20a%20team%20tab%2C%20I%20get%20a%20%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fjavascript%2Fapi%2F%40microsoft%2Fteams-js%2Fmicrosoftteams.context%3Fview%3Dmsteams-client-js-latest%22%20target%3D%22_self%22%20rel%3D%22noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3EgroupId%3C%2FA%3E%26nbsp%3Band%20%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fjavascript%2Fapi%2F%40microsoft%2Fteams-js%2Fmicrosoftteams.context%3Fview%3Dmsteams-client-js-latest%22%20target%3D%22_self%22%20rel%3D%22noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3EuserObjectId%3C%2FA%3Efrom%20the%20Context%20object.%20So%20Teams%20suggests%20that%20this%20user%20at%20the%20moment%20has%20access%20to%20that%20team%20because%20otherwise%20the%20Context%20object%20would%20not%20contain%20these%20values.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EAs%20the%20Context%20object%20could%20be%20compromised%2C%20I%20need%20a%20way%20to%20ascertain%20that%20this%20person%20actually%20belongs%20to%20that%20Team.%20I%20should%20be%20able%20to%20use%20the%20%3CEM%3Eme%2FjoinedTeams%3C%2FEM%3Eendpoint%20on%20the%20Graph%2C%20but%20because%20of%20the%20admin-level%20permissions%20required%2C%20I%20cannot%2C%20which%20is%20strange%20as%20it%20is%20actually%20the%20%22me%22%20endpoint%20and%20you%20get%20very%20limited%20information%20back%2C%20not%20an%20actual%20array%20of%20Group%20objects%20(as%20also%20raised%20%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fgraph%2Fapi%2Fuser-list-joinedteams%3Fview%3Dgraph-rest-1.0%26amp%3Btabs%3Dhttp%22%20target%3D%22_self%22%20rel%3D%22noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3Ehere%3C%2FA%3E%2C%20but%20that%20is%20another%20discussion%20in%20itself).%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EI've%20raised%20this%20point%20to%20Bill%20Bliss%2C%26nbsp%3BPlatform%20Architect%20and%20Head%20of%20Developer%20Ecosystem%20Microsoft%20Teams%2C%20and%20%3CA%20href%3D%22https%3A%2F%2Ftwitter.com%2Fbill_bliss%2Fstatus%2F1164384562387927040%22%20target%3D%22_self%22%20rel%3D%22nofollow%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3Ehe%20told%20me%3C%2FA%3Ethat%20more%20fine-grained%20permissions%20are%20coming.%20However%2C%20I'm%20wondering%20whether%20there%20is%20%3CSTRONG%3Eany%20other%20way%20%3C%2FSTRONG%3EI%20could%20ensure%20that%20a%20user%20belongs%20to%20a%20team.%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-856564%22%20slang%3D%22en-US%22%3ERe%3A%20Validating%20a%20user's%20membership%20of%20a%20Team%20-%20Context%20object%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-856564%22%20slang%3D%22en-US%22%3E%3CP%3E%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F405102%22%20target%3D%22_blank%22%3E%40salvijansen%3C%2FA%3E%20Yes%2C%20You%20can%20use%20your%20group%20id%20to%20fetch%20the%20list%20of%20members%20inside%20team.%20Please%20take%20a%20look%20at%20%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fgraph%2Fapi%2Fgroup-list-memberof%3Fview%3Dgraph-rest-1.0%26amp%3Btabs%3Dhttp%22%20target%3D%22_self%22%20rel%3D%22noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3EList%20memberOf%3C%2FA%3E%20for%20getting%20list%20of%20members%20in%20a%20team%20using%20Graph%20API.%20You%20can%20call%20this%20API%20endpoint%20%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fgraph%2Fapi%2Fgroup-list-memberof%3Fview%3Dgraph-rest-1.0%26amp%3Btabs%3Dhttp%22%20target%3D%22_self%22%20rel%3D%22noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3Ehttps%3A%2F%2Fgraph.microsoft.com%2Fv1.0%2Fgroups%2F%7Bgroup-id-for-teams%7D%2Fmembers.%3C%2FA%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-920802%22%20slang%3D%22en-US%22%3ERe%3A%20Validating%20a%20user's%20membership%20of%20a%20Team%20-%20Context%20object%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-920802%22%20slang%3D%22en-US%22%3EmemberOf%20requires%20%22Group.Read.All%22%20which%20needs%20to%20be%20granted%20by%20an%20admin%20and%20as%20I%20have%20said%20twice%20now%2C%20that%20is%20not%20what%20I'm%20looking%20for.%3C%2FLINGO-BODY%3E
salvijansen
Occasional Contributor

We should use the values from the Context object with due care, as someone might be running our app in a rogue environment, injecting values to manipulate the outcome.

 

For the user's login, I understand that we use it as a login hint and the authentication flow will always end in an interactive logon screen if that login hint is unknown. So we are pretty safe there.

 

But what about the organisationId / teamId if you have created a Team tab. How can we check whether that user is actually part of that team, if we only have user-delegated access? If we want to consult the me/joinedTeams or Groups endpoints of Microsoft Graph, we need admin-level consent (only permissions ending in ".All" can do this query). I really want to avoid needing admin consent (for obvious reasons).

4 Replies

@salvijansen, Thanks for reaching us. FYI,

Some high-privilege permissions in the Microsoft ecosystem can be set to admin-restricted. Examples of these kinds of permissions include the following:

  • Read all user's full profiles by using User.Read.All
  • Write data to an organization's directory by using Directory.ReadWrite.All
  • Read all groups in an organization's directory by using Groups.Read.All
  • Although a consumer user might grant an application access to this kind of data, organizational users are restricted from granting access to the same set of sensitive company data. If your application requests access to one of these permissions from an organizational user, the user receives an error message that says they're not authorized to consent to your app's permissions

For more information please have a look at documentation for Admin Restricted Permissions.

@Trinetra-MSFT Hi Trinetra, thank you for your reply!

 

I know the reasoning behind the admin-level permissions, but at the moment I'm not able to check the team id I get from the Context object. When launched as a team tab, I get a groupId and userObjectId from the Context object. So Teams suggests that this user at the moment has access to that team because otherwise the Context object would not contain these values.

 

As the Context object could be compromised, I need a way to ascertain that this person actually belongs to that Team. I should be able to use the me/joinedTeams endpoint on the Graph, but because of the admin-level permissions required, I cannot, which is strange as it is actually the "me" endpoint and you get very limited information back, not an actual array of Group objects (as also raised here, but that is another discussion in itself).

 

I've raised this point to Bill Bliss, Platform Architect and Head of Developer Ecosystem Microsoft Teams, and he told me that more fine-grained permissions are coming. However, I'm wondering whether there is any other way I could ensure that a user belongs to a team.

@salvijansen Yes, You can use your group id to fetch the list of members inside team. Please take a look at List memberOf for getting list of members in a team using Graph API. You can call this API endpoint https://graph.microsoft.com/v1.0/groups/{group-id-for-teams}/members.

 

 

memberOf requires "Group.Read.All" which needs to be granted by an admin and as I have said twice now, that is not what I'm looking for.
Related Conversations
Stable version of Edge insider browser
HotCakeX in Discussions on
35 Replies
Tabs and Dark Mode
cjc2112 in Discussions on
30 Replies
flashing a white screen while open new tab
Deleted in Discussions on
14 Replies
Security Community Webinars
Valon_Kolica in Security, Privacy & Compliance on
7 Replies