Skip to content

Commit 46c4b0a

Browse files
authored
Merge pull request #40 from damienbod/dev
Update .NET 10
2 parents cef91fa + b958d04 commit 46c4b0a

File tree

8 files changed

+77
-67
lines changed

8 files changed

+77
-67
lines changed

.github/workflows/dotnet.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
- name: Setup .NET
1717
uses: actions/setup-dotnet@v4
1818
with:
19-
dotnet-version: '9.0'
19+
dotnet-version: '10.0'
2020
include-prerelease: True
2121
- name: Build AngularMicrosoftEntraIDMultipleApis
2222
run: dotnet build ./AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis.sln
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using Microsoft.AspNetCore.Authentication;
2+
using Microsoft.AspNetCore.OpenApi;
3+
using Microsoft.OpenApi;
4+
5+
internal sealed class BearerSecuritySchemeTransformer(IAuthenticationSchemeProvider authenticationSchemeProvider) : IOpenApiDocumentTransformer
6+
{
7+
public async Task TransformAsync(OpenApiDocument document, OpenApiDocumentTransformerContext context, CancellationToken cancellationToken)
8+
{
9+
var authenticationSchemes = await authenticationSchemeProvider.GetAllSchemesAsync();
10+
if (authenticationSchemes.Any(authScheme => authScheme.Name == "Bearer"))
11+
{
12+
var requirements = new Dictionary<string, IOpenApiSecurityScheme>
13+
{
14+
["Bearer"] = new OpenApiSecurityScheme
15+
{
16+
Type = SecuritySchemeType.Http,
17+
Scheme = "bearer", // "bearer" refers to the header name here
18+
In = ParameterLocation.Header,
19+
BearerFormat = "Json Web Token"
20+
}
21+
};
22+
document.Components ??= new OpenApiComponents();
23+
document.Components.SecuritySchemes = requirements;
24+
}
25+
document.Info = new()
26+
{
27+
Title = "My API Bearer scheme",
28+
Version = "v1",
29+
Description = "API for Damien"
30+
};
31+
}
32+
}

AppRoles/WebApiWithRoles/Program.cs

Lines changed: 22 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
using Microsoft.AspNetCore.Authentication.JwtBearer;
21
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
32
using Microsoft.AspNetCore.Authorization;
43
using Microsoft.AspNetCore.Mvc.Authorization;
54
using Microsoft.Identity.Web;
65
using Microsoft.IdentityModel.JsonWebTokens;
7-
using Microsoft.OpenApi.Models;
86

97
var builder = WebApplication.CreateBuilder(args);
108

@@ -23,41 +21,19 @@
2321
options.TokenValidationParameters.NameClaimType = "name";
2422
});
2523

26-
builder.Services.AddSwaggerGen(c =>
24+
builder.Services.AddOpenApi(options =>
2725
{
28-
// add JWT Authentication
29-
var securityScheme = new OpenApiSecurityScheme
30-
{
31-
Name = "JWT Authentication",
32-
Description = "Enter JWT Bearer token **_only_**",
33-
In = ParameterLocation.Header,
34-
Type = SecuritySchemeType.Http,
35-
Scheme = "bearer", // must be lower case
36-
BearerFormat = "JWT",
37-
Reference = new OpenApiReference
38-
{
39-
Id = JwtBearerDefaults.AuthenticationScheme,
40-
Type = ReferenceType.SecurityScheme
41-
}
42-
};
43-
c.AddSecurityDefinition(securityScheme.Reference.Id, securityScheme);
44-
c.AddSecurityRequirement(new OpenApiSecurityRequirement
45-
{
46-
{securityScheme, Array.Empty<string>()}
47-
});
48-
49-
c.SwaggerDoc("v1", new OpenApiInfo
50-
{
51-
Title = "Web API with roles",
52-
Version = "v1",
53-
Description = "Web API with roles",
54-
Contact = new OpenApiContact
55-
{
56-
Name = "damienbod",
57-
Email = string.Empty,
58-
Url = new Uri("https://damienbod.com/"),
59-
},
60-
});
26+
//options.UseTransformer((document, context, cancellationToken) =>
27+
//{
28+
// document.Info = new()
29+
// {
30+
// Title = "My API",
31+
// Version = "v1",
32+
// Description = "API for Damien"
33+
// };
34+
// return Task.CompletedTask;
35+
//});
36+
options.AddDocumentTransformer<BearerSecuritySchemeTransformer>();
6137
});
6238

6339
builder.Services.AddAuthorization(policies =>
@@ -113,13 +89,6 @@
11389
app.UseDeveloperExceptionPage();
11490
}
11591

116-
app.UseSwagger();
117-
app.UseSwaggerUI(c =>
118-
{
119-
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Web API with roles");
120-
c.RoutePrefix = string.Empty;
121-
});
122-
12392
app.UseHttpsRedirection();
12493

12594
app.UseRouting();
@@ -129,4 +98,14 @@
12998

13099
app.MapControllers();
131100

101+
app.MapOpenApi("/openapi/v1/openapi.json");
102+
103+
if (app.Environment.IsDevelopment())
104+
{
105+
app.UseSwaggerUI(options =>
106+
{
107+
options.SwaggerEndpoint("/openapi/v1/openapi.json", "v1");
108+
});
109+
}
110+
132111
app.Run();
Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
<Project Sdk="Microsoft.NET.Sdk.Web">
22

33
<PropertyGroup>
4-
<TargetFramework>net8.0</TargetFramework>
4+
<TargetFramework>net10.0</TargetFramework>
55
<Nullable>enable</Nullable>
66
<ImplicitUsings>enable</ImplicitUsings>
77
</PropertyGroup>
88

99
<ItemGroup>
10-
<PackageReference Include="Microsoft.Identity.Web" Version="3.5.0" />
11-
<PackageReference Include="Swashbuckle.AspNetCore" Version="7.2.0" />
10+
<PackageReference Include="Microsoft.Identity.Web" Version="4.1.1" />
11+
12+
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.0" />
13+
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="10.0.1" />
1214
</ItemGroup>
1315

1416
</Project>

AppRoles/WebAppWithRoles/ClientApiWithRoles/ClientApiWithRolesService.cs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using Microsoft.Identity.Web;
2-
using Newtonsoft.Json.Linq;
32
using System.Net.Http.Headers;
43

54
namespace WebAppWithRoles;
@@ -19,30 +18,30 @@ public ClientApiWithRolesService(IHttpClientFactory clientFactory,
1918
_configuration = configuration;
2019
}
2120

22-
public async Task<JArray> GetUserDataFromApi()
21+
public async Task<string> GetUserDataFromApi()
2322
{
2423
return await GetDataFromApi("userdata");
2524
}
2625

27-
public async Task<JArray> GetStudentDataFromApi()
26+
public async Task<string> GetStudentDataFromApi()
2827
{
2928
return await GetDataFromApi("studentdata");
3029
}
3130

32-
public async Task<JArray> GetAdminDataFromApi()
31+
public async Task<string> GetAdminDataFromApi()
3332
{
3433
return await GetDataFromApi("admindata");
3534
}
3635

3736

38-
private async Task<JArray> GetDataFromApi(string path)
37+
private async Task<string> GetDataFromApi(string path)
3938
{
4039
var client = _clientFactory.CreateClient();
4140

4241
var scope = _configuration["ApiWithRoles:ScopeForAccessToken"];
43-
var accessToken = await _tokenAcquisition.GetAccessTokenForUserAsync(new[] { scope });
42+
var accessToken = await _tokenAcquisition.GetAccessTokenForUserAsync([scope!]);
4443

45-
client.BaseAddress = new Uri(_configuration["ApiWithRoles:ApiBaseAddress"]);
44+
client.BaseAddress = new Uri(_configuration["ApiWithRoles:ApiBaseAddress"]!);
4645
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
4746
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
4847

@@ -51,11 +50,10 @@ private async Task<JArray> GetDataFromApi(string path)
5150
{
5251
var responseContent = await response.Content.ReadAsStringAsync();
5352

54-
var data = JArray.Parse(responseContent);
55-
56-
return data;
53+
return responseContent;
5754
}
58-
var errorList = new List<string> { $"Status code: {response.StatusCode}", $"Error: {response.ReasonPhrase}" };
59-
return JArray.FromObject(errorList);
55+
var errorList = $"Status code: {response.StatusCode} Error: {response.ReasonPhrase}";
56+
57+
return errorList;
6058
}
6159
}

AppRoles/WebAppWithRoles/Pages/ClientWithRolesApi.cshtml.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using Microsoft.AspNetCore.Mvc.RazorPages;
22
using Microsoft.Identity.Web;
3-
using Newtonsoft.Json.Linq;
43

54
namespace WebAppWithRoles.Pages;
65

@@ -9,9 +8,9 @@ public class ClientWithRolesApiModel : PageModel
98
{
109
private readonly ClientApiWithRolesService _apiService;
1110

12-
public JArray? UserDataFromApi { get; set; }
13-
public JArray? StudentDataFromApi { get; set; }
14-
public JArray? AdminDataFromApi { get; set; }
11+
public string? UserDataFromApi { get; set; }
12+
public string? StudentDataFromApi { get; set; }
13+
public string? AdminDataFromApi { get; set; }
1514

1615
public ClientWithRolesApiModel(ClientApiWithRolesService apiService)
1716
{
Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
<Project Sdk="Microsoft.NET.Sdk.Web">
22

33
<PropertyGroup>
4-
<TargetFramework>net8.0</TargetFramework>
4+
<TargetFramework>net10.0</TargetFramework>
55
<UserSecretsId>bdff93cf-79ea-4b5e-aeaf-ea1490d39566</UserSecretsId>
66
<Nullable>enable</Nullable>
77
<ImplicitUsings>enable</ImplicitUsings>
88
</PropertyGroup>
99

1010
<ItemGroup>
11-
<PackageReference Include="Microsoft.Identity.Web" Version="3.5.0" />
12-
<PackageReference Include="Microsoft.Identity.Web.UI" Version="3.5.0" />
13-
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="9.0.0" />
11+
<PackageReference Include="Microsoft.Identity.Web" Version="4.1.1" />
12+
<PackageReference Include="Microsoft.Identity.Web.UI" Version="4.1.1" />
1413
</ItemGroup>
1514

1615
</Project>

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
## History
2121

22+
- 2025-12-14 .NET 10
2223
- 2025-02-07 Small updates
2324
- 2025-01-03 .NET 9, Bootstrap 5
2425
- 2024-04-11 Updated packages

0 commit comments

Comments
 (0)