diff --git a/AStar.Web.slnx b/AStar.Web.slnx
index 56164e8..2e6f39a 100644
--- a/AStar.Web.slnx
+++ b/AStar.Web.slnx
@@ -1,34 +1,36 @@
-
+
+
+
-
-
-
+
+
+
-
+
-
-
+
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
diff --git a/Directory.Build.props b/Directory.Build.props
new file mode 100644
index 0000000..ee33b71
--- /dev/null
+++ b/Directory.Build.props
@@ -0,0 +1,22 @@
+
+
+ true
+ net10.0
+ enable
+ true
+
+ $(InterceptorsNamespaces);Microsoft.AspNetCore.OpenApi.Generated
+
+ $(Features);InterceptorsPreview
+
+
+
+ True
+ 1701;1702;
+
+
+
+ True
+ 1701;1702;
+
+
diff --git a/blazor auth notes.md b/blazor auth notes.md
new file mode 100644
index 0000000..6c406f6
--- /dev/null
+++ b/blazor auth notes.md
@@ -0,0 +1,57 @@
+✅ Blazor + Entra ID App Role Access Control Checklist
+
+🔧 App Registration Setup
+
+- App role defined in the App Registration manifest (e.g., "Admin").
+- App Registration is treated as an API:
+ - Application ID URI is set (e.g., api://{client-id}).
+ - At least one scope is defined under “Expose an API”.
+ - accessTokenAcceptedVersion is set to 2 in the manifest.
+
+
+
+👥 Role Assignment
+
+- Users or groups are assigned to the app role via Enterprise Applications → Users and groups.
+- Role assignment is done on the service principal of the API App Registration.
+
+🔐 Token Request Configuration
+
+- Blazor app requests token for the API scope:
+
+ - Example: api://{API-App-ClientId}/.default
+
+
+- MSAL or Microsoft Identity Web is configured to request scopes correctly.
+
+🧾 Token Validation
+
+- Token contains the roles claim:
+
+- Use https://jwt.ms to inspect the token.
+- Confirm "roles": ["Admin"] is present.
+
+
+
+🧰 Blazor Authorization Setup
+
+- Authentication is configured using AddMicrosoftIdentityWebApp.
+- Authorization policy is defined:
+
+```C#
+options.AddPolicy("AdminOnly", policy => policy.RequireRole("Admin"));Show more lines
+```
+
+ Razor components/pages are protected:
+
+```C#
+@attribute [Authorize(Roles = "Admin")]
+```
+
+🧪 Testing
+
+- Test with a user assigned to the role.
+- Confirm access is granted to protected pages.
+- Test with a user not assigned to the role.
+- Confirm access is denied or redirected.
+
diff --git a/src/aspire/AStar.Web.AppHost/AStar.Web.AppHost.csproj b/src/aspire/AStar.Web.AppHost/AStar.Web.AppHost.csproj
index 9c9d7af..cea54b8 100644
--- a/src/aspire/AStar.Web.AppHost/AStar.Web.AppHost.csproj
+++ b/src/aspire/AStar.Web.AppHost/AStar.Web.AppHost.csproj
@@ -10,7 +10,7 @@
-
+
diff --git a/src/aspire/AStar.Web.AppHost/AppHost.cs b/src/aspire/AStar.Web.AppHost/AppHost.cs
index ece3ffb..75adab0 100644
--- a/src/aspire/AStar.Web.AppHost/AppHost.cs
+++ b/src/aspire/AStar.Web.AppHost/AppHost.cs
@@ -11,4 +11,4 @@
.WithReference(apiService)
.WaitFor(apiService);
-builder.Build().Run();
\ No newline at end of file
+builder.Build().Run();
diff --git a/src/aspire/AStar.Web.ServiceDefaults/Extensions.cs b/src/aspire/AStar.Web.ServiceDefaults/Extensions.cs
index c2e04a3..ae9f3ef 100644
--- a/src/aspire/AStar.Web.ServiceDefaults/Extensions.cs
+++ b/src/aspire/AStar.Web.ServiceDefaults/Extensions.cs
@@ -64,9 +64,8 @@ public static TBuilder ConfigureOpenTelemetry(this TBuilder builder)
tracing.AddSource(builder.Environment.ApplicationName)
.AddAspNetCoreInstrumentation(tracing =>
// Exclude health check requests from tracing
- tracing.Filter = context =>
- !context.Request.Path.StartsWithSegments(HealthEndpointPath)
- && !context.Request.Path.StartsWithSegments(AlivenessEndpointPath)
+ tracing.Filter = context => !context.Request.Path.StartsWithSegments(HealthEndpointPath)
+ && !context.Request.Path.StartsWithSegments(AlivenessEndpointPath)
)
// Uncomment the following line to enable gRPC instrumentation (requires the OpenTelemetry.Instrumentation.GrpcNetClient package)
//.AddGrpcClientInstrumentation()
@@ -123,4 +122,4 @@ public static WebApplication MapDefaultEndpoints(this WebApplication app)
return app;
}
-}
\ No newline at end of file
+}
diff --git a/src/modules/apis/AStar.Web.ApiService/AStar.Web.ApiService.csproj b/src/modules/apis/AStar.Web.ApiService/AStar.Web.ApiService.csproj
index 98b9f47..c99d52d 100644
--- a/src/modules/apis/AStar.Web.ApiService/AStar.Web.ApiService.csproj
+++ b/src/modules/apis/AStar.Web.ApiService/AStar.Web.ApiService.csproj
@@ -7,6 +7,8 @@
+
+
diff --git a/src/modules/apis/AStar.Web.ApiService/Program.cs b/src/modules/apis/AStar.Web.ApiService/Program.cs
index f0c1c43..9e9707c 100644
--- a/src/modules/apis/AStar.Web.ApiService/Program.cs
+++ b/src/modules/apis/AStar.Web.ApiService/Program.cs
@@ -1,3 +1,5 @@
+using Asp.Versioning;
+
var builder = WebApplication.CreateBuilder(args);
// Add service defaults & Aspire client integrations.
@@ -5,6 +7,17 @@
// Add services to the container.
builder.Services.AddProblemDetails();
+_ = builder.Services.AddApiVersioning(options =>
+ {
+ options.DefaultApiVersion = new ApiVersion(1, 0);
+ options.AssumeDefaultVersionWhenUnspecified = true;
+ options.ReportApiVersions = true;
+ })
+ .AddApiExplorer(options =>
+ {
+ options.GroupNameFormat = "'v'VVV";
+ options.SubstituteApiVersionInUrl = true;
+ });
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
builder.Services.AddOpenApi();
@@ -23,13 +36,12 @@
app.MapGet("/weatherforecast", () =>
{
- var forecast = Enumerable.Range(1, 5).Select(index =>
- new WeatherForecast
- (
- DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
- Random.Shared.Next(-20, 55),
- summaries[Random.Shared.Next(summaries.Length)]
- ))
+ var forecast = Enumerable.Range(1, 5).Select(index => new WeatherForecast
+ (
+ DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
+ Random.Shared.Next(-20, 55),
+ summaries[Random.Shared.Next(summaries.Length)]
+ ))
.ToArray();
return forecast;
})
@@ -42,4 +54,4 @@
internal record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
{
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
-}
\ No newline at end of file
+}
diff --git a/src/uis/AStar.Dev.Web/AStar.Dev.Web.csproj b/src/uis/AStar.Dev.Web/AStar.Dev.Web.csproj
index da9a099..6cc27b2 100644
--- a/src/uis/AStar.Dev.Web/AStar.Dev.Web.csproj
+++ b/src/uis/AStar.Dev.Web/AStar.Dev.Web.csproj
@@ -1,13 +1,43 @@
- net10.0
- enable
- enable
+ true
+ true
+ d7e61e34-084f-4c2b-9be8-5925170dc3b7
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/uis/AStar.Dev.Web/Components/App.razor b/src/uis/AStar.Dev.Web/Components/App.razor
index af64487..9baa660 100644
--- a/src/uis/AStar.Dev.Web/Components/App.razor
+++ b/src/uis/AStar.Dev.Web/Components/App.razor
@@ -1,21 +1,54 @@
-
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
\ No newline at end of file
+