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,15 +120,16 @@ 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.
132
+
- Click on 'Grant admin consent for (your tenant)'.
138
133
139
134
#### Configure your application to receive the **groups** claim
140
135
@@ -193,12 +188,13 @@ Open the project in your IDE (like Visual Studio) to configure the code.
193
188
1. Find the app key `Domain` and replace the existing value with your Azure AD tenant name.
194
189
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.
195
190
196
-
### Step 4: Run the sample
191
+
##Running the sample
197
192
198
193
1. Clean and rebuild the solution, and run it.
199
194
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.
195
+
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.
200
196
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`.
201
-
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.
197
+
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.
202
198
203
199
> 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.
204
200
@@ -314,14 +310,8 @@ The following files have the code that would be of interest to you:
314
310
315
311
1. HomeController.cs
316
312
1. Passes the **HttpContext.User** (the signed-in user) to the view.
317
-
1. UserProfileController.cs
318
-
1. Uses the **IMSGraphService** methods to fetch the signed-in user's group memberships.
319
-
1. IMSGraphService.cs, MSGraphService.cs and UserGroupsAndDirectoryRoles.cs
320
-
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).
321
313
1. Home\Index.cshtml
322
314
1. This has some code to print the current user's claims
323
-
1. UserProfile\Index.cshtml
324
-
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.
325
315
1. Startup.cs
326
316
327
317
- at the top of the file, add the following using directive:
@@ -340,43 +330,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.
350
+
351
+
`AddMicrosoftGraph` registers the service for `GraphServiceClient`. The values for BaseUrl and Scopes defined in `GraphAPI` section of **appsettings.json**.
352
+
353
+
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.
354
+
355
+
```csharp
356
+
public static async Task ProcessClaimsForGroupsOverage(TokenValidatedContext context)
var exMsg = graphEx.InnerException != null ? graphEx.InnerException.Message : graphEx.Message;
380
+
Console.WriteLine("Call to Microsoft Graph failed: "+ exMsg);
381
+
}
382
+
if (memberPage?.Count > 0)
383
+
{
384
+
var allgroups = ProcessIGraphServiceMemberOfCollectionPage(memberPage);
385
+
if (allgroups?.Count > 0)
386
+
{
387
+
var identity = (ClaimsIdentity)context.Principal.Identity;
388
+
if (identity != null)
389
+
{
390
+
RemoveExistingClaims(identity);
391
+
List<Claim> groupClaims = new List<Claim>();
392
+
foreach (Group group in allgroups)
393
+
{
394
+
groupClaims.Add(new Claim("groups", group.Id));
395
+
}
396
+
}
397
+
}
398
+
}
399
+
}
400
+
}
401
+
....
402
+
}
403
+
```
404
+
405
+
1. UserProfile\Index.cshtml
406
+
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`.
407
+
350
408
## How to deploy this sample to Azure
351
409
352
410
This project has one WebApp project. To deploy that to Azure Web Sites, you'll need to:
353
411
354
412
- create an Azure Web Site
355
-
- publish the Web App / Web APIs to the web site, and
356
-
- update its client(s) to call the web site instead of IIS Express.
413
+
- publish the project to the web site, and
414
+
- update its client(s) to call the web site instead of the local environment.
357
415
358
416
### Create and publish the `WebApp-GroupClaims` to an Azure Web Site
359
417
360
418
1. Sign in to the [Azure portal](https://portal.azure.com).
361
419
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`.
362
-
1. Thereafter select the `Subscription`, `Resource Group`, `App service plan and Location`. `OS` will be **Windows** and `Publish` will be **Code**.
420
+
1. Next, select the `Subscription`, `Resource Group`, `App service plan and Location`. `OS` will be **Windows** and `Publish` will be **Code**.
363
421
1. Click `Create` and wait for the App Service to be created.
364
422
1. Once you get the `Deployment succeeded` notification, then click on `Go to resource` to navigate to the newly created App service.
365
423
1. Once the web site is created, locate it it in the **Dashboard** and click it to open **App Services** **Overview** screen.
366
-
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.
424
+
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.
367
425
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.
368
-
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**.
426
+
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**.
369
427
1. On the Settings tab, make sure `Enable Organizational Authentication` is NOT selected. Click **Save**. Click on **Publish** on the main screen.
370
428
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.
371
429
372
-
### Update the Active Directory tenant application registration for `WebApp-GroupClaims`
430
+
### Update the Azure AD app registration for `WebApp-GroupClaims`
373
431
374
432
1. Navigate back to the [Azure portal](https://portal.azure.com).
375
433
In the left-hand navigation pane, select the **Azure Active Directory** service, and then select **App registrations (Preview)**.
376
-
1. In the resultant screen, select the `WebApp-GroupClaims` application.
377
-
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)
434
+
1. In the resulting screen, select the `WebApp-GroupClaims` application.
435
+
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)
378
436
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.
379
-
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.
437
+
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.
438
+
439
+
> :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.
440
+
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