You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
description: "Add authorization using groups & group claims to an ASP.NET Core Web app that signs-in users with the Microsoft identity platform"
10
+
name: Add authorization using groups & group claims to an ASP.NET Core Web app that signs-in users with the Microsoft identity platform
11
+
description: "This sample demonstrates a ASP.NET Core Web App application calling The Microsoft Graph"
18
12
---
19
13
20
14
# Add authorization using groups & group claims to an ASP.NET Core Web app that signs-in users with the Microsoft identity platform
@@ -37,21 +31,21 @@ This sample first leverages the ASP.NET Core OpenID Connect middleware to sign i
37
31
38
32
> An Identity Developer session covered Azure AD App roles and security groups, featuring this scenario and how to handle the overage claim. Watch the video [Using Security Groups and Application Roles in your apps](https://www.youtube.com/watch?v=LRoc-na27l0)
- An Azure Active Directory (Azure AD) tenant. For more information on how to get an Azure AD tenant, see [How to get an Azure AD tenant](https://azure.microsoft.com/documentation/articles/active-directory-howto-tenant/)
46
38
- A user account in your Azure AD tenant. This sample will not work with a **personal Microsoft account**. Therefore, if you signed in to the [Azure portal](https://portal.azure.com) with a personal account and have never created a user account in your directory before, you need to do that now.
47
39
48
40
> Please make sure to have one or more user accounts in the tenant assigned to a few security groups in your tenant. Please follow the instructions in [Create a basic group and add members using Azure Active Directory](https://docs.microsoft.com/azure/active-directory/fundamentals/active-directory-groups-create-azure-portal) to create a few groups and assign users to them if not already done.
@@ -65,19 +59,19 @@ Navigate to the `"5-WebApp-AuthZ"` folder
65
59
cd 5-WebApp-AuthZ\5-2-Groups
66
60
```
67
61
68
-
### Step 2: Register the sample application with your Azure Active Directory tenant
62
+
## Register the sample application with your Azure Active Directory tenant
69
63
70
64
There is one project in this sample. To register it, you can:
71
65
72
-
- either follow the step [Choose the Azure AD tenant where you want to create your applications](#choose-the-azure-ad-tenant-where-you-want-to-create-your-applications) below
66
+
- either follow the steps below for manually register your apps
73
67
- or use PowerShell scripts that:
74
68
-**automatically** creates the Azure AD applications and related objects (passwords, permissions, dependencies) for you.
75
69
- modify the projects' configuration files.
76
70
77
71
<details>
78
72
<summary>Expand this section if you want to use this automation:</summary>
79
73
80
-
1. On Windows, run PowerShell and navigate to the root of the cloned directory
74
+
1. On Windows, run PowerShell as **Administrator**and navigate to the root of the cloned directory
81
75
1. In PowerShell run:
82
76
83
77
```PowerShell
@@ -97,14 +91,14 @@ There is one project in this sample. To register it, you can:
97
91
98
92
</details>
99
93
100
-
Follow the steps below to manually register and configure your application on Azure AD.
94
+
Follow the steps below to manually walk through the steps to register and configure the applications in the Azure portal.
101
95
102
-
####Choose the Azure AD tenant where you want to create your applications
96
+
### Choose the Azure AD tenant where you want to create your applications
103
97
104
98
As a first step you'll need to:
105
99
106
100
1. Sign in to the [Azure portal](https://portal.azure.com).
107
-
1. If your account is present in more than one Azure AD tenant, select your profile at the top right corner in the menu on top of the page, and then **switch directory**.
101
+
1. If your account is present in more than one Azure AD tenant, select your profile at the top right corner in the menu on top of the page, and then **switch directory** to change your portal session to the desired Azure AD tenant.
108
102
109
103
#### Register the web app (WebApp-GroupClaims)
110
104
@@ -126,14 +120,14 @@ As a first step you'll need to:
126
120
1. In the app's registration screen, click on the **Certificates & secrets** blade in the left to open the page where we can generate secrets and upload certificates.
127
121
1. In the **Client secrets** section, click on **New client secret**:
128
122
- Type a key description (for instance `app secret`),
129
-
- Select one of the available key durations (**In 1 year**, **In 2 years**, or **Never Expires**) as per your security concerns.
123
+
- Select one of the available key durations (**In 1 year**, **In 2 years**, or **Never Expires**) as per your security posture.
130
124
- The generated key value will be displayed when you click the **Add** button. Copy the generated value for use in the steps later.
131
125
- You'll need this key later in your code's configuration files. This key value will not be displayed again, and is not retrievable by any other means, so make sure to note it from the Azure portal before navigating to any other screen or blade.
132
126
1. In the app's registration screen, click on the **API permissions** blade in the left to open the page where we add access to the APIs that your application needs.
133
127
- Click the **Add a permission** button and then,
134
128
- Ensure that the **Microsoft APIs** tab is selected.
135
129
- In the *Commonly used Microsoft APIs* section, click on **Microsoft Graph**
136
-
- In the **Delegated permissions** section, select the **GroupMember.Read.All** in the list. Use the search box if necessary.
130
+
- In the **Delegated permissions** section, select the **User.Read** and **GroupMember.Read.All** in the list. Use the search box if necessary.
137
131
- Click on the **Add permissions** button at the bottom.
138
132
1. At this stage permissions are assigned correctly and the **GroupMember.Read.All** requires admin to consent.
139
133
Click the **Grant/revoke admin consent for {tenant}** button, and then select **Yes** when you are asked if you want to grant consent for the
@@ -197,12 +191,13 @@ Open the project in your IDE (like Visual Studio) to configure the code.
197
191
1. Find the app key `Domain` and replace the existing value with your Azure AD tenant name.
198
192
1. Find the app key `ClientSecret` and replace the existing value with the key you saved during the creation of the `WebApp-GroupClaims` app, in the Azure portal.
199
193
200
-
### Step 4: Run the sample
194
+
##Running the sample
201
195
202
196
1. Clean and rebuild the solution, and run it.
203
197
1. Open your web browser and make a request to the app. The app immediately attempts to authenticate you to the Microsoft identity platform. You can sign-in with a *work or school account* from the tenant where you created this app. But sign-in with admin for the first time as admin consent is required for `GroupMember.Read.All` permission.
198
+
1. If the **Overage** scenario occurs for the signed-in user then all the groups are retrieved from Microsoft Graph and added in a list. The [overage](#groups-overage-claim) scenario is discussed later in this article.
204
199
1. On the home page, the app lists the various claims it obtained from your ID token. You'd notice one more claims named `groups`.
205
-
1. On the top menu, click on the signed-in user's name **[email protected]**, you should now see all kind of information about yourself including their picture. Beneath that, a list of all the security groups that the signed-in user is assigned to are listed as well. All of this was obtained by making calls to Microsoft Graph. This list is useful if the **Overage** scenario occurs with this signed-in user. The [overage](#groups-overage-claim) scenario is discussed later in this article.
200
+
1. On the top menu, click on the signed-in user's name **[email protected]**, you should now see all kind of information about yourself including their picture.
206
201
207
202
> Did the sample not work for you as expected? Did you encounter issues trying this sample? Then please reach out to us using the [GitHub Issues](../../../../issues) page.
208
203
@@ -318,14 +313,8 @@ The following files have the code that would be of interest to you:
318
313
319
314
1. HomeController.cs
320
315
1. Passes the **HttpContext.User** (the signed-in user) to the view.
321
-
1. UserProfileController.cs
322
-
1. Uses the **IMSGraphService** methods to fetch the signed-in user's group memberships.
323
-
1. IMSGraphService.cs, MSGraphService.cs and UserGroupsAndDirectoryRoles.cs
324
-
1. Uses the [Microsoft Graph SDK](https://github.com/microsoftgraph/msgraph-sdk-dotnet) to carry out various operations with [Microsoft Graph](https://graph.microsoft.com).
325
316
1. Home\Index.cshtml
326
317
1. This has some code to print the current user's claims
327
-
1. UserProfile\Index.cshtml
328
-
1. Has some client code that prints the signed-in user's information obtained from the [/me](https://docs.microsoft.com/graph/api/user-get?view=graph-rest-1.0), [/me/photo](https://docs.microsoft.com/graph/api/profilephoto-get) and [/memberOf](https://docs.microsoft.com/graph/api/user-list-memberof) endpoints.
329
318
1. Startup.cs
330
319
331
320
- at the top of the file, add the following using directive:
@@ -344,43 +333,114 @@ The following files have the code that would be of interest to you:
`OnTokenValidated` event calls **ProcessClaimsForGroupsOverage** method, that is defined in GraphHelper.cs, to process groups overage claim.
353
+
354
+
`AddMicrosoftGraph` registers the service for `GraphServiceClient`. The values for BaseUrl and Scopes defined in `GraphAPI` section of **appsettings.json**.
355
+
356
+
1. In GraphHelper.cs, ProcessClaimsForGroupsOverage method uses `GraphServiceClient` to retrieve groups for the signed-in user from [/me/memberOf](https://docs.microsoft.com/graph/api/user-list-memberof) endpoint. All the groups are stored in list of claims and the data can be used in the application as per requirement.
357
+
358
+
```csharp
359
+
public static async Task ProcessClaimsForGroupsOverage(TokenValidatedContext context)
var exMsg = graphEx.InnerException != null ? graphEx.InnerException.Message : graphEx.Message;
383
+
Console.WriteLine("Call to Microsoft Graph failed: "+ exMsg);
384
+
}
385
+
if (memberPage?.Count > 0)
386
+
{
387
+
var allgroups = ProcessIGraphServiceMemberOfCollectionPage(memberPage);
388
+
if (allgroups?.Count > 0)
389
+
{
390
+
var identity = (ClaimsIdentity)context.Principal.Identity;
391
+
if (identity != null)
392
+
{
393
+
RemoveExistingClaims(identity);
394
+
List<Claim> groupClaims = new List<Claim>();
395
+
foreach (Group group in allgroups)
396
+
{
397
+
groupClaims.Add(new Claim("groups", group.Id));
398
+
}
399
+
}
400
+
}
401
+
}
402
+
}
403
+
}
404
+
....
405
+
}
406
+
```
407
+
408
+
1. UserProfile\Index.cshtml
409
+
1. Has some client code that prints the signed-in user's information obtained from the [/me](https://docs.microsoft.com/graph/api/user-get?view=graph-rest-1.0) and [/me/photo](https://docs.microsoft.com/graph/api/profilephoto-get) endpoints by using `GraphServiceClient`.
410
+
354
411
## How to deploy this sample to Azure
355
412
356
413
This project has one WebApp project. To deploy that to Azure Web Sites, you'll need to:
357
414
358
415
- create an Azure Web Site
359
-
- publish the Web App / Web APIs to the web site, and
360
-
- update its client(s) to call the web site instead of IIS Express.
416
+
- publish the project to the web site, and
417
+
- update its client(s) to call the web site instead of the local environment.
361
418
362
419
### Create and publish the `WebApp-GroupClaims` to an Azure Web Site
363
420
364
421
1. Sign in to the [Azure portal](https://portal.azure.com).
365
422
1. Click `Create a resource` in the top left-hand corner, select **Web** --> **Web App**, and give your web site a name, for example, `WebApp-GroupClaims-contoso.azurewebsites.net`.
366
-
1. Thereafter select the `Subscription`, `Resource Group`, `App service plan and Location`. `OS` will be **Windows** and `Publish` will be **Code**.
423
+
1. Next, select the `Subscription`, `Resource Group`, `App service plan and Location`. `OS` will be **Windows** and `Publish` will be **Code**.
367
424
1. Click `Create` and wait for the App Service to be created.
368
425
1. Once you get the `Deployment succeeded` notification, then click on `Go to resource` to navigate to the newly created App service.
369
426
1. Once the web site is created, locate it it in the **Dashboard** and click it to open **App Services** **Overview** screen.
370
-
1. From the **Overview** tab of the App Service, download the publish profile by clicking the **Get publish profile** link and save it. Other deployment mechanisms, such as from source control, can also be used.
427
+
1. From the **Overview** tab of the App Service, download the publish profile by clicking the **Get publish profile** link and save it. Other deployment mechanisms, such as from **source control**, can also be used.
371
428
1. Switch to Visual Studio and go to the WebApp-GroupClaims project. Right click on the project in the Solution Explorer and select **Publish**. Click **Import Profile** on the bottom bar, and import the publish profile that you downloaded earlier.
372
-
1. Click on **Configure** and in the `Connection tab`, update the Destination URL so that it is a `https` in the home page url, for example [https://WebApp-GroupClaims-contoso.azurewebsites.net](https://WebApp-GroupClaims-contoso.azurewebsites.net). Click **Next**.
429
+
1. Click on **Configure** and in the `Connection tab`, update the Destination URL so that it is a `https` in the home page URL, for example [https://WebApp-GroupClaims-contoso.azurewebsites.net](https://WebApp-GroupClaims-contoso.azurewebsites.net). Click **Next**.
373
430
1. On the Settings tab, make sure `Enable Organizational Authentication` is NOT selected. Click **Save**. Click on **Publish** on the main screen.
374
431
1. Visual Studio will publish the project and automatically open a browser to the URL of the project. If you see the default web page of the project, the publication was successful.
375
432
376
-
### Update the Active Directory tenant application registration for `WebApp-GroupClaims`
433
+
### Update the Azure AD app registration for `WebApp-GroupClaims`
377
434
378
435
1. Navigate back to the [Azure portal](https://portal.azure.com).
379
436
In the left-hand navigation pane, select the **Azure Active Directory** service, and then select **App registrations (Preview)**.
380
-
1. In the resultant screen, select the `WebApp-GroupClaims` application.
381
-
1. In the **Authentication** | page for your application, update the Logout URL fields with the address of your service, for example [https://WebApp-GroupClaims-contoso.azurewebsites.net](https://WebApp-GroupClaims-contoso.azurewebsites.net)
437
+
1. In the resulting screen, select the `WebApp-GroupClaims` application.
438
+
1. In the **Authentication** page for your application, update the Logout URL fields with the address of your service, for example [https://WebApp-GroupClaims-contoso.azurewebsites.net](https://WebApp-GroupClaims-contoso.azurewebsites.net)
382
439
1. From the *Branding* menu, update the **Home page URL**, to the address of your service, for example [https://WebApp-GroupClaims-contoso.azurewebsites.net](https://WebApp-GroupClaims-contoso.azurewebsites.net). Save the configuration.
383
-
1. Add the same URL in the list of values of the *Authentication -> Redirect URIs* menu. If you have multiple redirect urls, make sure that there a new entry using the App service's Uri for each redirect url.
440
+
1. Add the same URL in the list of values of the *Authentication -> Redirect URIs* menu. If you have multiple redirect URIs, make sure that there a new entry using the App service's URI for each redirect URIs.
441
+
442
+
> :warning: If your app is using an *in-memory* storage, **Azure App Services** will spin down your web site if it is inactive, and any records that your app was keeping will emptied.
443
+
In addition, if you increase the instance count of your web site, requests will be distributed among the instances. Your app's records, therefore, will not be the same on each instance.
0 commit comments