Skip to content

Commit 1c4b6a2

Browse files
committed
Changes to use Session data for Authorization
1 parent 175121b commit 1c4b6a2

File tree

7 files changed

+86
-11
lines changed

7 files changed

+86
-11
lines changed

5-WebApp-AuthZ/5-2-Groups/AppCreationScripts/Configure.ps1

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,8 @@ Function ConfigureApplications
253253
Write-Host "- For 'webApp'"
254254
Write-Host " - Navigate to '$webAppPortalUrl'"
255255
Write-Host " - Navigate to the API Permissions page and select 'Grant admin consent for (your tenant)'" -ForegroundColor Red
256+
Write-Host " - On Azure Portal, create a security group named GroupAdmin, assign some users to it, and configure your ID and Access token to emit GroupID in your app registration. Configure the value for 'GroupAdmin' key in appsettings.json." -ForegroundColor Red
257+
Write-Host " - On Azure Portal, create a security group named GroupMember, assign some users to it, and configure your ID and Access token to emit GroupID in your app registration. Configure the value for 'GroupMember' key in appsettings.json." -ForegroundColor Red
256258

257259
Write-Host -ForegroundColor Green "------------------------------------------------------------------------------------------------"
258260

5-WebApp-AuthZ/5-2-Groups/AppCreationScripts/sample.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@
3131
"ManualSteps": [
3232
{
3333
"Comment": "Navigate to the API Permissions page and select 'Grant admin consent for (your tenant)'"
34+
},
35+
{
36+
"Comment": "On Azure Portal, create a security group named GroupAdmin, assign some users to it, and configure your ID and Access token to emit GroupID in your app registration. Configure the value for 'GroupAdmin' key in appsettings.json."
37+
},
38+
{
39+
"Comment": "On Azure Portal, create a security group named GroupMember, assign some users to it, and configure your ID and Access token to emit GroupID in your app registration. Configure the value for 'GroupMember' key in appsettings.json."
3440
}
3541
]
3642
}

5-WebApp-AuthZ/5-2-Groups/Controllers/UserProfileController.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using Microsoft.AspNetCore.Mvc;
1+
using Microsoft.AspNetCore.Authorization;
2+
using Microsoft.AspNetCore.Mvc;
23
using Microsoft.Graph;
34
using Microsoft.Identity.Web;
45
using System.Threading.Tasks;
@@ -16,7 +17,7 @@ public UserProfileController(GraphServiceClient graphServiceClient)
1617
{
1718
this.graphServiceClient= graphServiceClient;
1819
}
19-
20+
[Authorize(Policy = "GroupAdmin")]
2021
[AuthorizeForScopes(Scopes = new[] { Constants.ScopeUserRead })]
2122
public async Task<IActionResult> Index()
2223
{
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
using Microsoft.AspNetCore.Authorization;
2+
using Microsoft.AspNetCore.Http;
3+
using Microsoft.AspNetCore.Mvc.Filters;
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Linq;
7+
using System.Threading.Tasks;
8+
namespace WebApp_OpenIDConnect_DotNet.Infrastructure
9+
{
10+
public class GroupPolicyHandler : AuthorizationHandler<GroupPolicyRequirement>
11+
{
12+
private IHttpContextAccessor _httpContextAccessor;
13+
14+
public GroupPolicyHandler(IHttpContextAccessor httpContextAccessor)
15+
{
16+
_httpContextAccessor = httpContextAccessor;
17+
}
18+
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
19+
GroupPolicyRequirement requirement)
20+
{
21+
// Checks if groups claim exists in claims collection of signed-in User.
22+
if (context.User.Claims.Any(x => x.Type == "groups"))
23+
{
24+
if (context.User.Claims.Any(x => x.Type == "groups" && x.Value == requirement.GroupName))
25+
{
26+
context.Succeed(requirement);
27+
}
28+
return Task.CompletedTask;
29+
}
30+
31+
// Checks if Session contains data for groupClaims.
32+
// The data will exist for 'Group Overage' claim.
33+
else if (_httpContextAccessor.HttpContext.Session.Keys.Contains("groupClaims"))
34+
{
35+
// Retrieves all the groups saved in Session.
36+
var groups = _httpContextAccessor.HttpContext.Session.GetAsByteArray("groupClaims") as List<string>;
37+
groups = null;
38+
39+
// Checks if required group exists in Session.
40+
if (groups?.Count > 0 && groups.Contains(requirement.GroupName))
41+
{
42+
context.Succeed(requirement);
43+
}
44+
}
45+
return Task.CompletedTask;
46+
}
47+
}
48+
public class GroupPolicyRequirement : IAuthorizationRequirement
49+
{
50+
public string GroupName { get; }
51+
public GroupPolicyRequirement(string GroupName)
52+
{
53+
this.GroupName = GroupName;
54+
}
55+
}
56+
}

5-WebApp-AuthZ/5-2-Groups/Services/MicrosoftGraph-Rest/GraphHelper.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ public static async Task<List<string>> GetSignedInUsersGroups(TokenValidatedCont
8585
// groupClaims.Add(group.OnPremisesNetBiosName+"\\"+group.OnPremisesSamAccountName));
8686
groupClaims.Add(group.Id);
8787
}
88+
89+
// Here we add the groups in a session variable that is used in authorization policy handler.
90+
context.HttpContext.Session.SetAsByteArray("groupClaims", groupClaims);
8891
}
8992
}
9093
}
@@ -107,9 +110,6 @@ public static async Task<List<string>> GetSignedInUsersGroups(TokenValidatedCont
107110
}
108111
}
109112

110-
// Here we add the groups in a session variable to print on the home page for informational purposes
111-
context.HttpContext.Session.SetAsByteArray("groupClaims", groupClaims);
112-
113113
return groupClaims;
114114
}
115115

5-WebApp-AuthZ/5-2-Groups/Startup.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,20 +47,26 @@ public void ConfigureServices(IServiceCollection services)
4747
options.Events.OnTokenValidated = async context =>
4848
{
4949
//Calls method to process groups overage claim.
50-
await GraphHelper.GetSignedInUsersGroups(context);
50+
var groupClaims = await GraphHelper.GetSignedInUsersGroups(context);
51+
};
52+
options.Events.OnSignedOutCallbackRedirect = async context =>
53+
{
54+
context.HttpContext.Session.Clear();
5155
};
5256
}, options => { Configuration.Bind("AzureAd", options); })
5357
.EnableTokenAcquisitionToCallDownstreamApi(options => Configuration.Bind("AzureAd", options), initialScopes)
5458
.AddMicrosoftGraph(Configuration.GetSection("GraphAPI"))
5559
.AddInMemoryTokenCaches();
5660

57-
services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, options =>
61+
// Adding authorization policies that enforce authorization using group values.
62+
services.AddAuthorization(options =>
5863
{
59-
// The following code instructs the ASP.NET Core middleware to use the data in the "groups" claim in the [Authorize] attribute and for User.IsInRole()
60-
// Uncomment the following if you wish to use groups for roles
61-
// See https://docs.microsoft.com/en-us/aspnet/core/security/authorization/roles for more info.
62-
// options.TokenValidationParameters.RoleClaimType = "groups";
64+
options.AddPolicy("GroupAdmin",
65+
policy => policy.Requirements.Add(new GroupPolicyRequirement(Configuration["Groups:GroupAdmin"])));
66+
options.AddPolicy("GroupMember",
67+
policy => policy.Requirements.Add(new GroupPolicyRequirement(Configuration["Groups:GroupMember"])));
6368
});
69+
services.AddSingleton<IAuthorizationHandler, GroupPolicyHandler>();
6470

6571
services.AddDistributedMemoryCache();
6672
services.AddSession(options =>

5-WebApp-AuthZ/5-2-Groups/appsettings.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414
"BaseUrl": "https://graph.microsoft.com/v1.0",
1515
"Scopes": "User.Read GroupMember.Read.All"
1616
},
17+
"Groups": {
18+
"GroupAdmin": "Enter the objectID for GroupAdmin group copied from Azure Portal",
19+
"GroupMember": "Enter the objectID for GroupMember group copied from Azure Portal"
20+
},
1721
"Logging": {
1822
"LogLevel": {
1923
"Default": "Information",

0 commit comments

Comments
 (0)