-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ADDED: ADB2C.csproj updated with additional package references and pr…
…operties. ADDED: ADB2C.http file added, containing a GET request to the ADB2C host address. ADDED: ADB2C.sln file added project and solutionDED: MeController.cs file added, containing two controller methods for GET and configuration and middleware launch profiles for added, containing appsettings file added, containing configuration settings for Azure AD B2C, OpenID and allowed hosts.
- Loading branch information
Showing
8 changed files
with
395 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,22 @@ | ||
<Project Sdk="Microsoft.NET.Sdk.Web"> | ||
|
||
<PropertyGroup> | ||
<Title>Active Directory B2C Identity Test</Title> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<Nullable>enable</Nullable> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<InvariantGlobalization>true</InvariantGlobalization> | ||
<UserSecretsId>3c5831a3-10fe-4af0-8251-3b31ae14f177</UserSecretsId> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" /> | ||
<PackageReference Include="Microsoft.AspNetCore.Session" /> | ||
<PackageReference Include="Microsoft.Identity.Web" /> | ||
<PackageReference Include="Microsoft.Identity.Web.MicrosoftGraph" /> | ||
<PackageReference Include="Microsoft.Identity.Web.UI" /> | ||
<PackageReference Include="Azure.Extensions.AspNetCore.Configuration.Secrets" /> | ||
<PackageReference Include="Newtonsoft.Json" /> | ||
<PackageReference Include="Swashbuckle.AspNetCore" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
@ADB2C_HostAddress = http://localhost:5288 | ||
|
||
GET {{ADB2C_HostAddress}}/weatherforecast/ | ||
Accept: application/json | ||
|
||
### |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# | ||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B283EBC2-E01F-412D-9339-FD56EF114549}" | ||
ProjectSection(SolutionItems) = preProject | ||
..\Directory.Build.props = ..\Directory.Build.props | ||
..\Directory.Build.targets = ..\Directory.Build.targets | ||
..\..\..\global.json = ..\..\..\global.json | ||
..\..\..\Packages\Versions.Local.props = ..\..\..\Packages\Versions.Local.props | ||
EndProjectSection | ||
EndProject | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ADB2C", "ADB2C.csproj", "{1F05D736-EA65-4E82-9F14-EFDB324B2F63}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Local|Any CPU = Local|Any CPU | ||
Debug|Any CPU = Debug|Any CPU | ||
Testing|Any CPU = Testing|Any CPU | ||
Staging|Any CPU = Staging|Any CPU | ||
Production|Any CPU = Production|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{1F05D736-EA65-4E82-9F14-EFDB324B2F63}.Local|Any CPU.ActiveCfg = Local|Any CPU | ||
{1F05D736-EA65-4E82-9F14-EFDB324B2F63}.Local|Any CPU.Build.0 = Local|Any CPU | ||
{1F05D736-EA65-4E82-9F14-EFDB324B2F63}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{1F05D736-EA65-4E82-9F14-EFDB324B2F63}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{1F05D736-EA65-4E82-9F14-EFDB324B2F63}.Testing|Any CPU.ActiveCfg = Testing|Any CPU | ||
{1F05D736-EA65-4E82-9F14-EFDB324B2F63}.Testing|Any CPU.Build.0 = Testing|Any CPU | ||
{1F05D736-EA65-4E82-9F14-EFDB324B2F63}.Staging|Any CPU.ActiveCfg = Staging|Any CPU | ||
{1F05D736-EA65-4E82-9F14-EFDB324B2F63}.Staging|Any CPU.Build.0 = Staging|Any CPU | ||
{1F05D736-EA65-4E82-9F14-EFDB324B2F63}.Production|Any CPU.ActiveCfg = Local|Any CPU | ||
{1F05D736-EA65-4E82-9F14-EFDB324B2F63}.Production|Any CPU.Build.0 = Local|Any CPU | ||
{1F05D736-EA65-4E82-9F14-EFDB324B2F63}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{1F05D736-EA65-4E82-9F14-EFDB324B2F63}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
GlobalSection(ExtensibilityGlobals) = postSolution | ||
SolutionGuid = {E62FAA4C-9868-487A-AA4E-8DF41E52132B} | ||
EndGlobalSection | ||
EndGlobal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
namespace ADB2C.Controllers; | ||
|
||
using Microsoft.AspNetCore.Authorization; | ||
using Microsoft.AspNetCore.Mvc; | ||
using Microsoft.Identity.Web.Resource; | ||
using Microsoft.Identity.Web; | ||
using Microsoft.Graph; | ||
|
||
[Authorize(Policy = "alloweduser")] | ||
[ApiController] | ||
public class MeController(GraphServiceClient graphClient) : ControllerBase | ||
{ | ||
private readonly GraphServiceClient _graphClient = graphClient; | ||
|
||
[HttpGet] | ||
[Route("api/me")] | ||
[AuthorizeForScopes(ScopeKeySection = "AzureAdB2C:Scopes")] | ||
public async Task<User> Get() | ||
{ | ||
var graphUser = await _graphClient.Me | ||
.Request() | ||
// .Select( | ||
// u => | ||
// new | ||
// { | ||
// u.AboutMe, | ||
// u.AgeGroup, | ||
// u.AdditionalData, | ||
// u.Activities, | ||
// u.City, | ||
// u.Interests, | ||
// u.Identities | ||
// } | ||
// ) | ||
.GetAsync(); | ||
return graphUser; | ||
} | ||
|
||
[HttpPut] | ||
[Route("api/me")] | ||
[AuthorizeForScopes(ScopeKeySection = "AzureAdB2C:Scopes")] | ||
public async Task<User> Set([FromBody] System.Security.Claims.Claim claim) | ||
{ | ||
var graphUser = await _graphClient.Me | ||
.Request() | ||
.UpdateAsync( | ||
new User | ||
{ | ||
AdditionalData = new Dictionary<string, object> { { claim.Type, claim.Value } } | ||
} | ||
); | ||
return graphUser; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
using Microsoft.AspNetCore.Authentication.OpenIdConnect; | ||
using Microsoft.AspNetCore.HttpOverrides; | ||
using Microsoft.Identity.Web; | ||
using Microsoft.Identity.Web.UI; | ||
using Microsoft.AspNetCore.Authentication.Cookies; | ||
using Azure.Extensions.AspNetCore.Configuration.Secrets; | ||
using Azure.Identity; | ||
using Microsoft.AspNetCore.Authentication.JwtBearer; | ||
using System.IdentityModel.Tokens.Jwt; | ||
using Microsoft.IdentityModel.Logging; | ||
using Constants = Microsoft.Identity.Web.Constants; | ||
|
||
var builder = WebApplication.CreateBuilder(args); | ||
|
||
var initialScopes = builder.Configuration[ | ||
$"{nameof(MicrosoftGraphOptions)}:{nameof(MicrosoftGraphOptions.Scopes)}" | ||
]?.Split(' '); | ||
|
||
builder.Services.AddEndpointsApiExplorer(); | ||
builder.Services.AddOptions(); | ||
|
||
// Add services to the container. | ||
builder.Services | ||
.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) | ||
.AddMicrosoftIdentityWebApp(builder.Configuration.GetSection(Constants.AzureAdB2C)) | ||
.EnableTokenAcquisitionToCallDownstreamApi(initialScopes) | ||
.AddMicrosoftGraph(builder.Configuration.GetSection(nameof(MicrosoftGraphOptions))) | ||
.AddDistributedTokenCaches(); //we might need to change this to scale the app | ||
|
||
// builder.Services | ||
// .AddAuthentication(JwtBearerDefaults.AuthenticationScheme) | ||
// .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection(Constants.AzureAdB2C)) | ||
// .EnableTokenAcquisitionToCallDownstreamApi() | ||
// .AddMicrosoftGraph(builder.Configuration.GetSection(nameof(MicrosoftGraphOptions))) | ||
// .AddInMemoryTokenCaches(); | ||
|
||
builder.Services.AddSwaggerGen(c => c.SwaggerDoc("v1", new() { Title = "ADB2C", Version = "v1" })); | ||
|
||
// .AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) | ||
// .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection(Constants.AzureAd)) | ||
// .EnableTokenAcquisitionToCallDownstreamApi(initialScopes) | ||
// .AddMicrosoftGraph(builder.Configuration.GetSection(nameof(MicrosoftGraphOptions))) | ||
// .AddDistributedTokenCaches(); //we might need to change this to scale the app | ||
|
||
builder.Services.AddMicrosoftGraph(); | ||
Check failure on line 45 in Program.cs GitHub Actions / build
Check failure on line 45 in Program.cs GitHub Actions / build
|
||
builder.Services.AddProblemDetails(); | ||
builder.Services.AddHealthChecks(); | ||
JwtSecurityTokenHandler.DefaultMapInboundClaims = false; | ||
IdentityModelEventSource.LogCompleteSecurityArtifact = true; | ||
Check failure on line 49 in Program.cs GitHub Actions / build
|
||
IdentityModelEventSource.ShowPII = true; | ||
|
||
builder.Services.Configure<CookieAuthenticationOptions>( | ||
CookieAuthenticationDefaults.AuthenticationScheme, | ||
options => options.AccessDeniedPath = "/AccessDenied" | ||
); | ||
|
||
// builder.Services.Configure<JwtBearerOptions>( | ||
// JwtBearerDefaults.AuthenticationScheme, | ||
// options => | ||
// { | ||
// options.Events = new JwtBearerEvents { OnAuthenticationFailed = AuthenticationFailed }; | ||
// } | ||
// ); | ||
|
||
builder.Services.AddAuthorization(options => | ||
{ | ||
// By default, all incoming requests will be authorized according to the default policy. | ||
options.FallbackPolicy = options.DefaultPolicy; | ||
}); | ||
|
||
//if the access to the webapp needs to be limited to a specific role, set the role in the appsettings.json | ||
//if the role is not set, the webapp will be open to all authenticated users | ||
//this allows you to show a friendly access denied message with optional instructions for your users | ||
//how to get access if they want to or if they can | ||
//this access policy is set on the index.html and on the controller through [Authorize(Policy = "alloweduser")] attribute | ||
var requiredUserRoleForAccess = builder.Configuration["AzureAdB2C:AllowedUsersRole"]; | ||
if (!IsNullOrEmpty(requiredUserRoleForAccess)) | ||
Check failure on line 77 in Program.cs GitHub Actions / build
|
||
{ | ||
builder.Services | ||
.AddAuthorizationBuilder() | ||
.AddDefaultPolicy( | ||
"alloweduser", | ||
policy => | ||
{ | ||
policy.RequireAuthenticatedUser(); | ||
policy.RequireRole(requiredUserRoleForAccess); | ||
Check warning on line 86 in Program.cs GitHub Actions / build
|
||
} | ||
); | ||
} | ||
else | ||
{ | ||
builder.Services | ||
.AddAuthorizationBuilder() | ||
.AddDefaultPolicy("alloweduser", policy => policy.RequireAuthenticatedUser()); | ||
} | ||
|
||
builder.Services.Configure<SessionOptions>( | ||
builder.Configuration.GetSection(nameof(SessionOptions)) | ||
); | ||
builder.Services.AddSession(); | ||
|
||
// options => | ||
// { | ||
// options.IdleTimeout = TimeSpan.FromMinutes(1); //You can set Time | ||
// options.Cookie.IsEssential = true; | ||
// options.Cookie.SameSite = SameSiteMode.None; | ||
// options.Cookie.SecurePolicy = CookieSecurePolicy.Always; | ||
// options.Cookie.HttpOnly = true; | ||
// }); | ||
|
||
builder.Services.AddRazorPages().AddMicrosoftIdentityUI(); | ||
|
||
builder.Services.AddHttpClient(); // use iHttpFactory as best practice, should be easy to use extra retry and hold off policies in the future | ||
|
||
// The following lines code instruct the asp.net core middleware to use the data in the "roles" claim in the Authorize attribute and User.IsInrole() | ||
// See https://docs.microsoft.com/aspnet/core/security/authorization/roles?view=aspnetcore-2.2 for more info. | ||
builder.Services.Configure<OpenIdConnectOptions>( | ||
OpenIdConnectDefaults.AuthenticationScheme, | ||
builder.Configuration.GetSection(nameof(OpenIdConnectOptions)) | ||
); | ||
|
||
var app = builder.Build(); | ||
|
||
// this setting is used when you use tools like ngrok or reverse proxies like nginx which connect to http://localhost | ||
// if you don't set this setting the sign-in redirect will be http instead of https | ||
app.UseForwardedHeaders( | ||
new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedProto } | ||
); | ||
|
||
// Configure the HTTP request pipeline. | ||
if (app.Environment.IsDevelopment()) | ||
{ | ||
app.UseDeveloperExceptionPage(); | ||
app.UseSwagger(); | ||
app.UseSwaggerUI(); | ||
Check failure on line 135 in Program.cs GitHub Actions / build
|
||
} | ||
else | ||
{ | ||
app.UseHsts(); | ||
app.UseExceptionHandler("/Error"); | ||
} | ||
|
||
app.UseSession(); | ||
app.UseHttpsRedirection(); | ||
app.UseStaticFiles(); | ||
|
||
app.UseRouting(); | ||
|
||
app.UseAuthentication(); | ||
app.UseAuthorization(); | ||
|
||
app.UseCookiePolicy(new CookiePolicyOptions { Secure = CookieSecurePolicy.Always }); | ||
|
||
app.MapRazorPages(); | ||
app.MapControllers(); | ||
|
||
// generate an api-key on startup that we can use to validate callbacks | ||
env.SetEnvironmentVariable("API-KEY", guid.NewGuid().ToString()); | ||
Check failure on line 158 in Program.cs GitHub Actions / build
|
||
|
||
app.Run(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
{ | ||
"$schema": "http://json.schemastore.org/launchsettings.json", | ||
"iisSettings": { | ||
"windowsAuthentication": false, | ||
"anonymousAuthentication": true, | ||
"iisExpress": { | ||
"applicationUrl": "http://localhost:35859", | ||
"sslPort": 44365 | ||
} | ||
}, | ||
"profiles": { | ||
// "http": { | ||
// "commandName": "Project", | ||
// "dotnetRunMessages": true, | ||
// "launchBrowser": true, | ||
// "launchUrl": "swagger", | ||
// "applicationUrl": "https://localhost:5288", | ||
// "environmentVariables": { | ||
// "ASPNETCORE_ENVIRONMENT": "Development" | ||
// } | ||
// }, | ||
"https": { | ||
"commandName": "Project", | ||
"dotnetRunMessages": true, | ||
"launchBrowser": true, | ||
"launchUrl": "swagger", | ||
"applicationUrl": "https://localhost:7157;http://localhost:5288", | ||
"environmentVariables": { | ||
"ASPNETCORE_ENVIRONMENT": "Development" | ||
} | ||
}, | ||
"IIS Express": { | ||
"commandName": "IISExpress", | ||
"launchBrowser": true, | ||
"launchUrl": "swagger", | ||
"environmentVariables": { | ||
"ASPNETCORE_ENVIRONMENT": "Development" | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"Logging": { | ||
"LogLevel": { | ||
"Default": "Information", | ||
"Microsoft.AspNetCore": "Warning" | ||
} | ||
} | ||
} |
Oops, something went wrong.