Azure Active Directory, the advanced logo

Iterating Group memberships using Claims in .NET Core

This post was most recently updated on November 14th, 2021.

4 min read.

Another case, where there’s plenty of documentation, but it just doesn’t seem to be comprehensive enough or just doesn’t apply for any of the cases that I have – for whatever reason. Maybe my cases are wrong, or I’m just bad at googling, but I’ve struggled to find a good page documenting this.

Perfect case for another blog post about the topic, then – perhaps someone else will find it useful!

This post answers the question: How to get Claims for a user in .NET Core? Additionally, it answers how to configure your app in Azure AD to request Claims to be returned with the user principal. It also shows how to iterate these Claims in your C# code, using a group membership check as an example.

Introduction

I posted earlier about how to get the current user in .NET Core. That post leaves out some of the work that you will need to do before you even get to that point – a shortcoming, that was made painfully obvious by a couple of comments on that article.

This ties into the broader topic of gathering information about the current – or any other, for that matter – user in your system. I’ve posted something about this before, on how to handle the user object you get back, but I didn’t go into the details of configuring your application to actually request and use those Claims.

In this article, we’ll go through how to configure your application registration with Azure Active Directory to return the Claims detailing group memberships!

By default, you only have access to a few Claims. The screenshot below details this in action:

That’s it. But what if you want more? Like the guid of each Azure AD group (both security and Microsoft 365) that your user is a member of?

Solution

The solution consists of a couple of different steps. First of all, you need to force AAD to return the group membership info, and after that, you need to have a meaningful way of checking the claims in your code.

All clear at this point? Great, let’s jump into it!

Time needed: 20 minutes

How to access group membership claims from Azure AD?

  1. Open the app manifest editor in Azure AD Portal

    Find your app registration in the Azure AD Portal (https://aad.portal.azure.com), and then click Manifest on the left-hand side navigation.

  2. Modify the manifest to return all group membership claims

    You need to modify your application manifest file to explicitly, specifically request group membership claims to be returned. This happens by locating the “groupMembershipClaims” setting and setting its value to either “SecurityGroup” or “All”.

    The way these 2 work is as follows:
    1) SecurityGroup – Groups claim will contain the identifiers of all security groups of which the user is a member.
    2) All – Groups claim will contain the identifiers of all security groups and all distribution lists of which the user is a member

    The latter can easily contain hundreds of entries – so be aware of the (hopefully obvious) performance considerations! Only request the Security Groups if possible.

    Additionally, according to Microsoft’s documentation, you can also specify these values in the groupMembershipClaims – section (although I have never needed to specify them):
    3) DistributionList
    4) DirectoryRole

    In your application manifest JSON, it looks something like this:
    {

    “groupMembershipClaims”: “SecurityGroup”,

    }

    I’ve also included a whole example JSON as appendix 1 for your convenience.

  3. (Optional) Other claims options

    An interesting additional point can be made about the optionalClaims. You can use this part of the manifest to request additional claims from AAD. Basically, depending on how you’re configuring your application, you might need to request additional claims such as extended user profile properties through saml2Token by specifying additional claims. The same applies to varying degrees and use cases to idToken, saml2Token, and accessToken.

    The example below requests an extension attribute from Azure AD, like a property coming from on-prem Active Directory synchronization:
    {

    "optionalClaims": {
    "idToken": [],
    "accessToken": [],
    "saml2Token": [
    {
    "name": "extension_ab603c56068041afb2f6832e2a17e237_skypeId",
    "source": "user",
    "essential": true
    }
    ]
    },

    }

    Note, that in order to also retrieve the ID tokens or Access tokens directly to your application from Azure AD, you need to also enable the corresponding options under app registration > Authentication.

    How to enable Azure Active Directory to return tokens for your app? This form can be found under "Authentication" section of your Azure app registration.

    See more on the optional claims in the References section!

  4. Add the API permissions to request the Group memberships

    Basically, you’ll need either one of the two following permissions:
    – Groups.Read.All (recommended)
    – Directory.Read.All (higher permissions – also works)

    Both of these permissions require admin consent.

  5. How to access the Claims in your ASP.NET C# code?

    Next, you need to find a nice way to use the claims in your code.
    After the configuration above has been done, it’ll yield output like this to your user objects.



    The way you can use this, for example, would be to check the group membership of a user, like shown below – grab all Claims of type “groups” and compare their value to the ID (Guid) of your group.

    How to iterate Claims (group memberships) in your C# .NET Core code?
    How to iterate Claims (group memberships) in your C# .NET Core code?

And you should be good!

As a fairly large caveat, though, it’s useful to notice, that writing helper methods and calling them everywhere in your application is not a good way to check for permissions in ASP.NET Core. Instead, for anything larger than a few views and/or APIs, you should use authorization attributes and limit the visibility of your components using AuthorizeViews or build custom components on top of these. See References for more info.

References & Appendices

Appendix 1 – Example of an app manifest requesting group membership claims in Azure AD

{
	"id": "22af0087-1337-1337-1337-363738a49ea9",
	"acceptMappedClaims": null,
	"accessTokenAcceptedVersion": null,
	"addIns": [],
	"allowPublicClient": null,
	"appId": "9bbe55d1-1337-1337-1337-e69344bf7f2c",
	"appRoles": [],
	"oauth2AllowUrlPathMatching": false,
	"createdDateTime": "2019-09-03T20:11:34Z",
	"groupMembershipClaims": "All",
	"identifierUris": [],
	"informationalUrls": {
		"termsOfService": null,
		"support": null,
		"privacy": null,
		"marketing": null
	},
	"keyCredentials": [],
	"knownClientApplications": [],
	"logoUrl": null,
	"logoutUrl": null,
	"name": "appname",
	"oauth2AllowIdTokenImplicitFlow": true,
	"oauth2AllowImplicitFlow": true,
	"oauth2Permissions": [],
	"oauth2RequirePostResponse": false,
	"optionalClaims": null,
	"orgRestrictions": [],
	"parentalControlSettings": {
		"countriesBlockedForMinors": [],
		"legalAgeGroupRule": "Allow"
	}
	],
	"preAuthorizedApplications": [],
	"publisherDomain": "yourdomain.onmicrosoft.com",
	"replyUrlsWithType": [
		{
			"url": "https://localhost:44307/signin-oidc",
			"type": "Web"
		},
		{
			"url": "https://localhost:44307/",
			"type": "Web"
		}
	],
	"requiredResourceAccess": [
		{
			"resourceAppId": "00000003-0000-0000-c000-000000000000",
			"resourceAccess": [
				{
					"id": "64a6cdd6-aab1-4aaf-94b8-3cc8405e90d0",
					"type": "Scope"
				}
			]
		}
	],
	"samlMetadataUrl": null,
	"signInUrl": null,
	"signInAudience": "AzureADMyOrg",
	"tags": [],
	"tokenEncryptionKeyId": null
}
mm
5 1 vote
Article Rating
Subscribe
Notify of
guest

3 Comments
most voted
newest oldest
Inline Feedbacks
View all comments