diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml
index ef763fe..65c2484 100644
--- a/.github/workflows/dotnet.yml
+++ b/.github/workflows/dotnet.yml
@@ -16,7 +16,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
- dotnet-version: '9.0'
+ dotnet-version: '10.0'
include-prerelease: True
- name: Restore dependencies
run: dotnet restore
diff --git a/BlazorAuth0Bff/Client/BlazorAuth0Bff.Client.csproj b/BlazorAuth0Bff/Client/BlazorAuth0Bff.Client.csproj
index 4ee5b70..ff108da 100644
--- a/BlazorAuth0Bff/Client/BlazorAuth0Bff.Client.csproj
+++ b/BlazorAuth0Bff/Client/BlazorAuth0Bff.Client.csproj
@@ -1,17 +1,17 @@
- net9.0
+ net10.0
true
enable
enable
-
-
-
-
+
+
+
+
diff --git a/BlazorAuth0Bff/Server/BlazorAuth0Bff.Server.csproj b/BlazorAuth0Bff/Server/BlazorAuth0Bff.Server.csproj
index afda91c..a107faa 100644
--- a/BlazorAuth0Bff/Server/BlazorAuth0Bff.Server.csproj
+++ b/BlazorAuth0Bff/Server/BlazorAuth0Bff.Server.csproj
@@ -1,7 +1,7 @@
- net9.0
+ net10.0
enable
enable
de0b7f31-65d4-46d6-8382-30c94073cf4a
@@ -13,10 +13,10 @@
-
-
-
-
+
+
+
+
diff --git a/BlazorAuth0Bff/Server/appsettings.json b/BlazorAuth0Bff/Server/appsettings.json
index 306d92b..33081d8 100644
--- a/BlazorAuth0Bff/Server/appsettings.json
+++ b/BlazorAuth0Bff/Server/appsettings.json
@@ -10,7 +10,7 @@
"Microsoft.Hosting.Lifetime": "Information"
}
},
- "MyApiUrl": "https://localhost:44390",
+ "MyApiUrl": "https://localhost:5014",
"AllowedHosts": "*"
//"Auth0": {
// "Domain": "your-domain-in-auth0",
diff --git a/BlazorAuth0Bff/Shared/BlazorAuth0Bff.Shared.csproj b/BlazorAuth0Bff/Shared/BlazorAuth0Bff.Shared.csproj
index 4b5c766..9a4d7b5 100644
--- a/BlazorAuth0Bff/Shared/BlazorAuth0Bff.Shared.csproj
+++ b/BlazorAuth0Bff/Shared/BlazorAuth0Bff.Shared.csproj
@@ -1,7 +1,7 @@
- net9.0
+ net10.0
enable
enable
diff --git a/MyApi/Controllers/AzureADUserOneController.cs b/MyApi/Controllers/EntraIdUserOneController.cs
similarity index 70%
rename from MyApi/Controllers/AzureADUserOneController.cs
rename to MyApi/Controllers/EntraIdUserOneController.cs
index 9cdd026..92d1d34 100644
--- a/MyApi/Controllers/AzureADUserOneController.cs
+++ b/MyApi/Controllers/EntraIdUserOneController.cs
@@ -1,33 +1,30 @@
-using Microsoft.AspNetCore.Authorization;
-using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Mvc;
-using Microsoft.Identity.Web;
-using Swashbuckle.AspNetCore.Annotations;
-using System.Collections.Generic;
-
-namespace MyApi.Controllers;
-
-///
-/// API protected with Microsoft.Identity.Web and Microsoft Entra ID
-/// scope from App registration used to authorize.
-///
-[SwaggerTag("API protected with Microsoft.Identity.Web and Microsoft Entra ID")]
-[AuthorizeForScopes(Scopes = ["api://b2a09168-54e2-4bc4-af92-a710a64ef1fa/access_as_user"],
- AuthenticationScheme = "myADscheme")]
-[Authorize(AuthenticationSchemes = "myADscheme")]
-[ApiController]
-[Route("api/[controller]")]
-public class AzureADUserOneController : ControllerBase
-{
- ///
- /// returns data id the correct Microsoft Entra ID access token is used with the correct scope.
- ///
- /// protected data
- [HttpGet]
- [ProducesResponseType(StatusCodes.Status200OK)]
- [ProducesResponseType(StatusCodes.Status401Unauthorized)]
- public IEnumerable Get()
- {
- return new List { "Microsoft Entra ID user one data" };
- }
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Identity.Web;
+using System.Collections.Generic;
+
+namespace MyApi.Controllers;
+
+///
+/// API protected with Microsoft.Identity.Web and Microsoft Entra ID
+/// scope from App registration used to authorize.
+///
+[AuthorizeForScopes(Scopes = ["api://b2a09168-54e2-4bc4-af92-a710a64ef1fa/access_as_user"], AuthenticationScheme = "myADscheme")]
+[Authorize(AuthenticationSchemes = "myADscheme")]
+[ApiController]
+[Route("api/[controller]")]
+public class EntraIdUserOneController : ControllerBase
+{
+ ///
+ /// returns data id the correct Microsoft Entra ID access token is used with the correct scope.
+ ///
+ /// protected data
+ [HttpGet("")]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status401Unauthorized)]
+ public IEnumerable Get()
+ {
+ return ["Microsoft Entra ID user one data"];
+ }
}
\ No newline at end of file
diff --git a/MyApi/Controllers/ServiceTwoController.cs b/MyApi/Controllers/ServiceTwoController.cs
index 7646894..3edc45a 100644
--- a/MyApi/Controllers/ServiceTwoController.cs
+++ b/MyApi/Controllers/ServiceTwoController.cs
@@ -1,7 +1,6 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
-using Swashbuckle.AspNetCore.Annotations;
using System.Collections.Generic;
namespace MyApi.Controllers;
@@ -10,7 +9,6 @@ namespace MyApi.Controllers;
/// Service access token protected using Auth0
/// protected using "p-service-api-auth0" policy defined in the Startup
///
-[SwaggerTag("Service access token protected using Auth0 ")]
[Authorize(Policy = "p-service-api-auth0")]
[ApiController]
[Route("api/[controller]")]
diff --git a/MyApi/Controllers/UserOneController.cs b/MyApi/Controllers/UserOneController.cs
index 8ade4f2..33bea2c 100644
--- a/MyApi/Controllers/UserOneController.cs
+++ b/MyApi/Controllers/UserOneController.cs
@@ -1,7 +1,6 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
-using Swashbuckle.AspNetCore.Annotations;
using System.Collections.Generic;
namespace MyApi.Controllers;
@@ -10,7 +9,6 @@ namespace MyApi.Controllers;
/// User access token protected using Auth0
/// protected using "p-user-api-auth0" policy defined in the Startup
///
-[SwaggerTag("User access token protected using Auth0")]
[Authorize(Policy = "p-user-api-auth0")]
[ApiController]
[Route("api/[controller]")]
diff --git a/MyApi/MyApi.csproj b/MyApi/MyApi.csproj
index 528c977..6638493 100644
--- a/MyApi/MyApi.csproj
+++ b/MyApi/MyApi.csproj
@@ -1,7 +1,7 @@
- net9.0
+ net10.0
7b15921c-6a17-41fd-90cc-86a09d128527
true
$(NoWarn);1591
@@ -9,18 +9,18 @@
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
diff --git a/MyApi/Program.cs b/MyApi/Program.cs
index 443c454..ca1db61 100644
--- a/MyApi/Program.cs
+++ b/MyApi/Program.cs
@@ -1,17 +1,20 @@
+using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc.Authorization;
+using Microsoft.AspNetCore.OpenApi;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Identity.Web;
using Microsoft.IdentityModel.JsonWebTokens;
-using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi;
using MyApi;
using NetEscapades.AspNetCore.SecurityHeaders.Infrastructure;
-using System;
-using System.IO;
-using System.Reflection;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
var builder = WebApplication.CreateBuilder(args);
@@ -54,47 +57,19 @@
options.Audience = "https://auth0-api1";
});
-services.AddSwaggerGen(c =>
+services.AddOpenApi(options =>
{
- c.EnableAnnotations();
- // add JWT Authentication
- var securityScheme = new OpenApiSecurityScheme
- {
- Name = "JWT Authentication",
- Description = "Enter JWT Bearer token **_only_**",
- In = ParameterLocation.Header,
- Type = SecuritySchemeType.Http,
- Scheme = "bearer", // must be lower case
- BearerFormat = "JWT",
- Reference = new OpenApiReference
- {
- Id = JwtBearerDefaults.AuthenticationScheme,
- Type = ReferenceType.SecurityScheme
- }
- };
- c.AddSecurityDefinition(securityScheme.Reference.Id, securityScheme);
- c.AddSecurityRequirement(new OpenApiSecurityRequirement
- {
- {securityScheme, Array.Empty()}
- });
-
- c.SwaggerDoc("v1", new OpenApiInfo
- {
- Title = "My API",
- Version = "v1",
- Description = "My API",
- Contact = new OpenApiContact
- {
- Name = "damienbod",
- Email = string.Empty,
- Url = new Uri("https://damienbod.com/"),
- }
- });
-
- // Set the comments path for the Swagger JSON and UI.
- var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
- var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
- c.IncludeXmlComments(xmlPath);
+ //options.UseTransformer((document, context, cancellationToken) =>
+ //{
+ // document.Info = new()
+ // {
+ // Title = "My API",
+ // Version = "v1",
+ // Description = "API for Damien"
+ // };
+ // return Task.CompletedTask;
+ //});
+ options.AddDocumentTransformer();
});
services.AddSingleton();
@@ -130,18 +105,18 @@
app.UseSecurityHeaders();
-app.UseSwagger();
-app.UseSwaggerUI(c =>
+//app.MapOpenApi(); // /openapi/v1.json
+app.MapOpenApi("/openapi/v1/openapi.json");
+//app.MapOpenApi("/openapi/{documentName}/openapi.json");
+
+app.UseSwaggerUI(options =>
{
- c.SwaggerEndpoint("/swagger/v1/swagger.json", "User API");
- c.RoutePrefix = string.Empty;
+ options.SwaggerEndpoint("/openapi/v1/openapi.json", "v1");
});
// only needed for browser clients
// app.UseCors("AllowAllOrigins");
-app.UseHttpsRedirection();
-
app.UseRouting();
app.UseAuthentication();
@@ -150,3 +125,32 @@
app.MapControllers();
app.Run();
+
+internal sealed class BearerSecuritySchemeTransformer(IAuthenticationSchemeProvider authenticationSchemeProvider) : IOpenApiDocumentTransformer
+{
+ public async Task TransformAsync(OpenApiDocument document, OpenApiDocumentTransformerContext context, CancellationToken cancellationToken)
+ {
+ var authenticationSchemes = await authenticationSchemeProvider.GetAllSchemesAsync();
+ if (authenticationSchemes.Any(authScheme => authScheme.Name == "Bearer"))
+ {
+ var requirements = new Dictionary
+ {
+ ["Bearer"] = new OpenApiSecurityScheme
+ {
+ Type = SecuritySchemeType.Http,
+ Scheme = "bearer", // "bearer" refers to the header name here
+ In = ParameterLocation.Header,
+ BearerFormat = "Json Web Token"
+ }
+ };
+ document.Components ??= new OpenApiComponents();
+ document.Components.SecuritySchemes = requirements;
+ }
+ document.Info = new()
+ {
+ Title = "My API Bearer scheme",
+ Version = "v1",
+ Description = "API for Damien"
+ };
+ }
+}
\ No newline at end of file
diff --git a/MyApi/Properties/launchSettings.json b/MyApi/Properties/launchSettings.json
index 7ad22d0..1e59059 100644
--- a/MyApi/Properties/launchSettings.json
+++ b/MyApi/Properties/launchSettings.json
@@ -3,11 +3,11 @@
"MyApi": {
"commandName": "Project",
"launchBrowser": true,
- "launchUrl": "weatherforecast",
+ "launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
- "applicationUrl": "https://localhost:44390"
+ "applicationUrl": "https://localhost:5014"
}
}
}
\ No newline at end of file
diff --git a/RazorMicrosoftEntraID/CallMyApiOne/MyApiOneService.cs b/RazorMicrosoftEntraID/CallMyApiOne/MyApiOneService.cs
index 9eba962..29948bd 100644
--- a/RazorMicrosoftEntraID/CallMyApiOne/MyApiOneService.cs
+++ b/RazorMicrosoftEntraID/CallMyApiOne/MyApiOneService.cs
@@ -28,13 +28,13 @@ public async Task> GetApiDataAsync()
var client = _clientFactory.CreateClient();
var scope = _configuration["MyApiOne:ScopeForAccessToken"];
- var accessToken = await _tokenAcquisition.GetAccessTokenForUserAsync(new List { scope! });
+ var accessToken = await _tokenAcquisition.GetAccessTokenForUserAsync([scope!]);
client.BaseAddress = new Uri(_configuration["MyApiOne:ApiBaseAddress"]!);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
- var response = await client.GetAsync("api/AzureADUserOne");
+ var response = await client.GetAsync("api/EntraIdUserOne");
if (response.IsSuccessStatusCode)
{
var responseContent = await response.Content.ReadAsStringAsync();
diff --git a/RazorMicrosoftEntraID/Pages/Shared/_Layout.cshtml b/RazorMicrosoftEntraID/Pages/Shared/_Layout.cshtml
index e35cd92..1ba7539 100644
--- a/RazorMicrosoftEntraID/Pages/Shared/_Layout.cshtml
+++ b/RazorMicrosoftEntraID/Pages/Shared/_Layout.cshtml
@@ -39,7 +39,7 @@
diff --git a/RazorMicrosoftEntraID/RazorMicrosoftEntraID.csproj b/RazorMicrosoftEntraID/RazorMicrosoftEntraID.csproj
index 3a9673b..0360063 100644
--- a/RazorMicrosoftEntraID/RazorMicrosoftEntraID.csproj
+++ b/RazorMicrosoftEntraID/RazorMicrosoftEntraID.csproj
@@ -1,18 +1,18 @@
- net9.0
+ net10.0
aspnet-RazorAzureAD-C5CB1E61-55D5-4D0D-A192-68F28533B4EA
1
enable
-
-
-
-
-
+
+
+
+
+
diff --git a/RazorMicrosoftEntraID/appsettings.json b/RazorMicrosoftEntraID/appsettings.json
index 508820f..18057a6 100644
--- a/RazorMicrosoftEntraID/appsettings.json
+++ b/RazorMicrosoftEntraID/appsettings.json
@@ -9,7 +9,7 @@
},
"MyApiOne": {
"ScopeForAccessToken": "api://b2a09168-54e2-4bc4-af92-a710a64ef1fa/access_as_user",
- "ApiBaseAddress": "https://localhost:44390"
+ "ApiBaseAddress": "https://localhost:5014"
},
"Logging": {
"LogLevel": {