diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index fa39c8f..c9de30b 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -12,11 +12,11 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Setup .NET - uses: actions/setup-dotnet@v1 + uses: actions/setup-dotnet@v4 with: - dotnet-version: '8.0' + dotnet-version: '9.0' include-prerelease: True - name: Build AngularMicrosoftEntraIDMultipleApis run: dotnet build ./AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis.sln diff --git a/.gitignore b/.gitignore index b0b6a46..0c76ac0 100644 --- a/.gitignore +++ b/.gitignore @@ -8,15 +8,7 @@ **/node_modules/ **/dist/ **/*.csproj.user -/AngularAzureADMultipleApis/LogsServiceApi.txt -/BlazorWithApis/LogsServiceApi.txt -/ConfidentialClientCredentialsCertificate/LogsServiceApi.txt -/ConfidentialClientCredentialsCertificate/LogsMyServerRenderedPortal.txt -/DecryptionCertificates/LogsApiDecryptionCertificates.txt -/DecryptionCertificates/LogsPortalDecryptionCertificates.txt /AngularAzureADMultipleApis/AngularAzureAD/debug.log -/ClientCredentialsFlows/LogsServiceApi.txt -/AngularAzureADMultipleApis/_logs-ApiWithMutlipleApis.txt -/AngularAzureADMultipleApis/_logs-ServiceApi.txt -/ConfidentialClientCredentialsCertificate/_logs-MyServerRenderedPortal.txt -/ConfidentialClientCredentialsCertificate/_logs-ServiceApi.txt +**/_logs* +**/Logs* +**/*.user diff --git a/AngularMicrosoftEntraIDMultipleApis/AngularCliMicrosoftEntraID/certs/dev_localhost.key b/AngularMicrosoftEntraIDMultipleApis/AngularCliMicrosoftEntraID/certs/dev_localhost.key index cc4f625..df045f2 100644 --- a/AngularMicrosoftEntraIDMultipleApis/AngularCliMicrosoftEntraID/certs/dev_localhost.key +++ b/AngularMicrosoftEntraIDMultipleApis/AngularCliMicrosoftEntraID/certs/dev_localhost.key @@ -1,13 +1,13 @@ -----BEGIN RSA PRIVATE KEY----- -MIICXQIBAAKBgQCs7HI0KWqXEjH1fxXdkgVHg+1UgbtBhwkeZ3WhBsTGcwlqGUmzqlhKiR2hTd9G -dMhQm1tFeU9qAMpmglxR+XgoZoEv9uoXw/TeegdKvn1V3exTxeULIDGJOXK6wQ1M+4FLMr7zBWlM -hWmqcbYTHHVwwYd+ycDRHU3NAIxDfMUSQQIDAQABAoGAIB8z/7iJ0lJQ8XeQCj6ruGMrXP1UWZHK -AdnaIfVt7CdGYm0cIcHM8NuTo3khtqbO5xpU1Az60YggEPa6S4f558kGBIg4PQVxgE/Kv77ptGAk -rZG9FaCyIibGMh5aJLtxG0Fh1FGnuK1Xk1BKXtaGRUkZpKGg4rMJ9w3qp/T5vLkCQQDe+FiMqY2s -pxHEz+h3NJ0H2T81FCx2upf1fjTVtlQnJ7Gds6eZT0zwa3z1bSw+VkxICERY8C43bzPUJUgPIyLX -AkEAxooyVkJHmxlcIvZfrZPvQs+2GOXpWVnyjNUWf8t9G2MsmkdGIkp7oJhi5obpdNR+3jQe0xyr -Dvy1hbHuGp5opwJBALO6Zc5EogGozgbiPBVSoL2B3ZRQhaLSt8jYCYi3JtBFC8P927wVkwQ88IX4 -kXBSKbzqhQVX3Tkr9xArWRFylhMCQFmigt9WxSVM6cAPI1smctrjE/9hrVxds5fJjILdx/nZaIWu -sAdDQVVb9yrEthm85hpDxbbiNohppzpY/nqeEfkCQQDInS/pP5dYTUxFV+/YweK+6smN2v+dYZAi -5KShWRl5fwpl+mdJT3aziRb/kfYkhGPQMO06OnGzjNKt7Rg0Z8mD +MIICXQIBAAKBgQDjQCAk+Otv72o+HPmieLtLIX0NzWDNc5vocj5p3hU+FNXS74SVWn/XiSAWsF/j ++VhQ8RU7AZWPslMYI/KHDr1PbE54ydQkOjoU6mwKWedQspYSWz9sAwMghV5KxR4bsGCvNYnmAupe +/lYUhx3DUOWGJulymcerntDEhhseABUDrQIDAQABAoGALVg9UcNNj09RfsVfVnkKvkoXXuqtNzGr +WW16YLuMt4+GvwlGBltBiSt2eLCG4cF+SuBgIR8Gzd6CUB3UJfjd8xvCGsnJ+7blaTxXPFpYKSdL +mAxgd2dZcltt9tUTDeMG2VroAiwHZR6ABJDbwmIaStW1JBjtu2u/LML1gjk+JM0CQQD97fRY4v/R +GCwFxZG9NkSUCRkCM4SpxeryChGwMymVoF/ugRhvw4VmR8qCFP8Set+KieXVZpeTGca/dmOtoBov +AkEA5Rp7ZiPp1zAyqWcqzeWAkfVPK9Cmfugs4tKBQkxHtdcb0OdObPd964HT1vH0lJ4eR/XhafWY +5q8rnwQAmyf04wJBAMNCpmFvdJ15w+hQS0g/Ia7f7A4oRXwzR/4ExiNCxFhdcUc6l+rhY4QJ8mvi +711rhNfIQCa/9BBWguEZjX6mnVsCQCaZuaTR9Do/cqm8KigavPjangZB12uWbsmgsgqbk5F9tsAR +2NLfOCYP78NNbOoFYhC5ysrxiFuFtBHMuNVrfAUCQQDqhqY1m1hyWXpOneFJbt4wHTun4QhLhJ6N +yijNL2phxhaM6SgT3lsF+lwjD44UkiT2JOnXwaNYEadK7G2aI0bK -----END RSA PRIVATE KEY----- diff --git a/AngularMicrosoftEntraIDMultipleApis/AngularCliMicrosoftEntraID/certs/dev_localhost.pem b/AngularMicrosoftEntraIDMultipleApis/AngularCliMicrosoftEntraID/certs/dev_localhost.pem index f2247c7..207caa6 100644 --- a/AngularMicrosoftEntraIDMultipleApis/AngularCliMicrosoftEntraID/certs/dev_localhost.pem +++ b/AngularMicrosoftEntraIDMultipleApis/AngularCliMicrosoftEntraID/certs/dev_localhost.pem @@ -1,13 +1,13 @@ -----BEGIN CERTIFICATE----- -MIICQDCCAamgAwIBAgIJAIKGapdMCt4NMA0GCSqGSIb3DQEBCwUAMBQxEjAQBgNVBAMTCWxvY2Fs -aG9zdDAeFw0yMDAyMjAyMjU3MjFaFw0zMDAyMjEyMjU3MjFaMBQxEjAQBgNVBAMTCWxvY2FsaG9z -dDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArOxyNClqlxIx9X8V3ZIFR4PtVIG7QYcJHmd1 -oQbExnMJahlJs6pYSokdoU3fRnTIUJtbRXlPagDKZoJcUfl4KGaBL/bqF8P03noHSr59Vd3sU8Xl -CyAxiTlyusENTPuBSzK+8wVpTIVpqnG2Exx1cMGHfsnA0R1NzQCMQ3zFEkECAwEAAaOBmTCBljAS -BgNVHRMBAf8ECDAGAQH/AgEDMA4GA1UdDwEB/wQEAwIB/jAUBgNVHREEDTALgglsb2NhbGhvc3Qw -OwYDVR0lBDQwMgYIKwYBBQUHAwEGCCsGAQUFBwMCBggrBgEFBQcDAwYIKwYBBQUHAwQGCCsGAQUF -BwMIMB0GA1UdDgQWBBQaVighscgq5k8BjEzeSsZp+6RxITANBgkqhkiG9w0BAQsFAAOBgQBXH/Sq -jekwz+O0eG0zA2MA2LSwt7OELi54vATFYkXO45IO5frRagUTWDkx85/Vfm9OcdfoaHD1UzPkGBU0 -BPsnN3SGCB3Pk5jSRaXIBBiqByDFiP+G6EYmUYhLxB3FpJp6S5KlnQtdtLkl3KuT8KBtc9haro+e -lDlUx5s/FM3SJw== +MIICPzCCAaigAwIBAgIIApLJQ1yKNwgwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAxMJbG9jYWxo +b3N0MB4XDTI1MDEwMTA5Mjc1N1oXDTM1MDEwMjA5Mjc1N1owFDESMBAGA1UEAxMJbG9jYWxob3N0 +MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDjQCAk+Otv72o+HPmieLtLIX0NzWDNc5vocj5p +3hU+FNXS74SVWn/XiSAWsF/j+VhQ8RU7AZWPslMYI/KHDr1PbE54ydQkOjoU6mwKWedQspYSWz9s +AwMghV5KxR4bsGCvNYnmAupe/lYUhx3DUOWGJulymcerntDEhhseABUDrQIDAQABo4GZMIGWMBIG +A1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgH+MBQGA1UdEQQNMAuCCWxvY2FsaG9zdDA7 +BgNVHSUENDAyBggrBgEFBQcDAQYIKwYBBQUHAwIGCCsGAQUFBwMDBggrBgEFBQcDBAYIKwYBBQUH +AwgwHQYDVR0OBBYEFInWKVCkc0wgw1x5XUBvFbFcbDPpMA0GCSqGSIb3DQEBCwUAA4GBADhiql/N +FTLa5oQCWt1Ot6xdvTXHEMf9f6okZkpcZ310IJO8OuptMKW+l+NvJNrpB20ef0XatzAxUVUtTdvz +UfbMQTu541Rf8/bdloiPS2ld8TZNQk4xe5kGbX9EegQ1QVseEhba5lQvQvBhefk4zDnK0Ve7TmY7 +5geNTUjDEcgC -----END CERTIFICATE----- diff --git a/AngularMicrosoftEntraIDMultipleApis/AngularCliMicrosoftEntraID/certs/dev_localhost.pfx b/AngularMicrosoftEntraIDMultipleApis/AngularCliMicrosoftEntraID/certs/dev_localhost.pfx index 737693d..89532c1 100644 Binary files a/AngularMicrosoftEntraIDMultipleApis/AngularCliMicrosoftEntraID/certs/dev_localhost.pfx and b/AngularMicrosoftEntraIDMultipleApis/AngularCliMicrosoftEntraID/certs/dev_localhost.pfx differ diff --git a/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/ApiWithMutlipleApis.csproj b/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/ApiWithMutlipleApis.csproj index 2c7c869..64b81de 100644 --- a/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/ApiWithMutlipleApis.csproj +++ b/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/ApiWithMutlipleApis.csproj @@ -1,32 +1,31 @@  - net8.0 + net9.0 3e9ac996-8e75-4dd9-9a5b-27a6e01a3f3d enable enable - - - + + + - - - + + + - - - - - - - - + + + + + + + + - - + diff --git a/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/Controllers/DelegatedUserApiCallsController.cs b/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/Controllers/DelegatedUserApiCallsController.cs index 7b2838e..243c19b 100644 --- a/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/Controllers/DelegatedUserApiCallsController.cs +++ b/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/Controllers/DelegatedUserApiCallsController.cs @@ -7,12 +7,12 @@ namespace ApiWithMutlipleApis.Controllers; [Authorize(Policy = "ValidateAccessTokenPolicy", AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] -[AuthorizeForScopes(Scopes = new string[] { "api://2b50a014-f353-4c10-aace-024f19a55569/access_as_user" })] +[AuthorizeForScopes(Scopes = ["api://2b50a014-f353-4c10-aace-024f19a55569/access_as_user"])] [ApiController] [Route("[controller]")] public class DelegatedUserApiCallsController : ControllerBase { - private UserApiClientService _userApiClientService; + private readonly UserApiClientService _userApiClientService; public DelegatedUserApiCallsController(UserApiClientService userApiClientService) { diff --git a/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/Controllers/DirectApiController.cs b/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/Controllers/DirectApiController.cs index 7f0350f..5407ae7 100644 --- a/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/Controllers/DirectApiController.cs +++ b/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/Controllers/DirectApiController.cs @@ -5,9 +5,8 @@ namespace ApiWithMutlipleApis.Controllers; -[Authorize(Policy = "ValidateAccessTokenPolicy", - AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] -[AuthorizeForScopes(Scopes = new string[] { "api://2b50a014-f353-4c10-aace-024f19a55569/access_as_user" })] +[Authorize(Policy = "ValidateAccessTokenPolicy", AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] +[AuthorizeForScopes(Scopes = ["api://2b50a014-f353-4c10-aace-024f19a55569/access_as_user"])] [ApiController] [Route("[controller]")] public class DirectApiController : ControllerBase @@ -15,6 +14,6 @@ public class DirectApiController : ControllerBase [HttpGet] public IEnumerable Get() { - return new List { "some data", "more data", "loads of data" }; + return ["some data", "more data", "loads of data"]; } } diff --git a/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/Controllers/GraphApiCallsController.cs b/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/Controllers/GraphApiCallsController.cs index 4778259..782b6d0 100644 --- a/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/Controllers/GraphApiCallsController.cs +++ b/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/Controllers/GraphApiCallsController.cs @@ -7,12 +7,12 @@ namespace ApiWithMutlipleApis.Controllers; [Authorize(Policy = "ValidateAccessTokenPolicy", AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] -[AuthorizeForScopes(Scopes = new string[] { "User.ReadBasic.All", "user.read" })] +[AuthorizeForScopes(Scopes = ["User.ReadBasic.All", "user.read"])] [ApiController] [Route("[controller]")] public class GraphApiCallsController : ControllerBase { - private GraphApiClientService _graphApiClientService; + private readonly GraphApiClientService _graphApiClientService; public GraphApiCallsController(GraphApiClientService graphApiClientService) { @@ -24,7 +24,7 @@ public async Task> Get() { var userData = await _graphApiClientService.GetGraphApiUser(); - return new List { $"DisplayName: {userData.DisplayName}", - $"GivenName: {userData.GivenName}", $"AboutMe: {userData.AboutMe}" }; + return [ $"DisplayName: {userData!.DisplayName}", + $"GivenName: {userData!.GivenName}", $"AboutMe: {userData!.AboutMe}" ]; } } diff --git a/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/Controllers/ServiceApiCallsController.cs b/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/Controllers/ServiceApiCallsController.cs index 605b627..77b8a74 100644 --- a/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/Controllers/ServiceApiCallsController.cs +++ b/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/Controllers/ServiceApiCallsController.cs @@ -7,12 +7,12 @@ namespace ApiWithMutlipleApis.Controllers; [Authorize(Policy = "ValidateAccessTokenPolicy", AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] -[AuthorizeForScopes(Scopes = new string[] { "api://2b50a014-f353-4c10-aace-024f19a55569/access_as_user" })] +[AuthorizeForScopes(Scopes = ["api://2b50a014-f353-4c10-aace-024f19a55569/access_as_user"])] [ApiController] [Route("[controller]")] public class ServiceApiCallsController : ControllerBase { - private ServiceApiClientService _serviceApiClientService; + private readonly ServiceApiClientService _serviceApiClientService; public ServiceApiCallsController(ServiceApiClientService serviceApiClientService) { diff --git a/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/Program.cs b/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/Program.cs index 7e4ad58..03fea1e 100644 --- a/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/Program.cs +++ b/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/Program.cs @@ -3,27 +3,25 @@ Log.Logger = new LoggerConfiguration() .WriteTo.Console() - .WriteTo.AzureApp() .CreateBootstrapLogger(); +Log.Information("Starting ApiWithMutlipleApis application"); + try { - Log.Information("Starting ApiWithMutlipleApis"); - -var builder = WebApplication.CreateBuilder(args); + var builder = WebApplication.CreateBuilder(args); + builder.Host.UseSerilog((context, loggerConfiguration) => loggerConfiguration + .WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}") + .ReadFrom.Configuration(context.Configuration)); -builder.Host.UseSerilog((context, loggerConfiguration) => loggerConfiguration - .ReadFrom.Configuration(context.Configuration)); + var app = builder + .ConfigureServices() + .ConfigurePipeline(); -var app = builder - .ConfigureServices() - .ConfigurePipeline(); - -app.Run(); + app.Run(); } -catch (Exception ex) when(ex.GetType().Name is not "StopTheHostException" - && ex.GetType().Name is not "HostAbortedException") +catch (Exception ex) when (ex.GetType().Name is not "StopTheHostException" && ex.GetType().Name is not "HostAbortedException") { Log.Fatal(ex, "Unhandled exception"); } @@ -31,4 +29,4 @@ { Log.Information("Shut down complete"); Log.CloseAndFlush(); -} +} \ No newline at end of file diff --git a/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/Services/ServiceApiClientService.cs b/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/Services/ServiceApiClientService.cs index 5a9cbcd..44a6a63 100644 --- a/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/Services/ServiceApiClientService.cs +++ b/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/Services/ServiceApiClientService.cs @@ -9,8 +9,7 @@ public class ServiceApiClientService private readonly IHttpClientFactory _clientFactory; private readonly ITokenAcquisition _tokenAcquisition; - public ServiceApiClientService( - ITokenAcquisition tokenAcquisition, + public ServiceApiClientService(ITokenAcquisition tokenAcquisition, IHttpClientFactory clientFactory) { _clientFactory = clientFactory; @@ -19,12 +18,10 @@ public ServiceApiClientService( public async Task> GetApiDataAsync() { - var client = _clientFactory.CreateClient(); var scope = "api://b178f3a5-7588-492a-924f-72d7887b7e48/.default"; // CC flow access_as_application"; - var accessToken = await _tokenAcquisition.GetAccessTokenForAppAsync(scope) - .ConfigureAwait(false); + var accessToken = await _tokenAcquisition.GetAccessTokenForAppAsync(scope); client.BaseAddress = new Uri("https://localhost:44324"); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); @@ -36,7 +33,7 @@ public async Task> GetApiDataAsync() var data = await JsonSerializer.DeserializeAsync>( await response.Content.ReadAsStreamAsync()); - if(data != null) + if (data != null) return data; return Array.Empty(); diff --git a/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/Services/UserApiClientService.cs b/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/Services/UserApiClientService.cs index 7b4fedf..784db9b 100644 --- a/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/Services/UserApiClientService.cs +++ b/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/Services/UserApiClientService.cs @@ -9,9 +9,7 @@ public class UserApiClientService private readonly IHttpClientFactory _clientFactory; private readonly ITokenAcquisition _tokenAcquisition; - public UserApiClientService( - ITokenAcquisition tokenAcquisition, - IHttpClientFactory clientFactory) + public UserApiClientService(ITokenAcquisition tokenAcquisition, IHttpClientFactory clientFactory) { _clientFactory = clientFactory; _tokenAcquisition = tokenAcquisition; @@ -19,7 +17,6 @@ public UserApiClientService( public async Task> GetApiDataAsync() { - var client = _clientFactory.CreateClient(); var scopes = new List { "api://b2a09168-54e2-4bc4-af92-a710a64ef1fa/access_as_user" }; @@ -37,10 +34,9 @@ public async Task> GetApiDataAsync() var data = await JsonSerializer.DeserializeAsync>(stream); - if (data != null) - return data; + if (data != null) return data; - return Array.Empty(); + return []; } throw new ApplicationException("oh no..."); diff --git a/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/HostingExtensions.cs b/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/StartupExtensions.cs similarity index 97% rename from AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/HostingExtensions.cs rename to AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/StartupExtensions.cs index b6f631a..7d2c5e5 100644 --- a/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/HostingExtensions.cs +++ b/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/StartupExtensions.cs @@ -9,7 +9,7 @@ namespace ApiWithMutlipleApis; -internal static class HostingExtensions +internal static class StartupExtensions { public static WebApplication ConfigureServices(this WebApplicationBuilder builder) { @@ -81,7 +81,7 @@ public static WebApplication ConfigureServices(this WebApplicationBuilder builde c.AddSecurityDefinition(securityScheme.Reference.Id, securityScheme); c.AddSecurityRequirement(new OpenApiSecurityRequirement { - {securityScheme, new string[] { }} + {securityScheme, Array.Empty()} }); c.SwaggerDoc("v1", new OpenApiInfo { Title = "ApiWithMutlipleApis", Version = "v1" }); @@ -89,7 +89,7 @@ public static WebApplication ConfigureServices(this WebApplicationBuilder builde return builder.Build(); } - + public static WebApplication ConfigurePipeline(this WebApplication app) { IdentityModelEventSource.ShowPII = true; @@ -105,12 +105,9 @@ public static WebApplication ConfigurePipeline(this WebApplication app) app.UseCors("AllowAllOrigins"); app.UseHttpsRedirection(); - app.UseRouting(); - app.UseAuthentication(); app.UseAuthorization(); - app.MapControllers(); return app; diff --git a/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/appsettings.json b/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/appsettings.json index 56e184e..5c8db09 100644 --- a/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/appsettings.json +++ b/AngularMicrosoftEntraIDMultipleApis/ApiWithMutlipleApis/appsettings.json @@ -5,29 +5,38 @@ "TenantId": "7ff95b15-dc21-4ba6-bc92-824856578fc1", "ClientId": "2b50a014-f353-4c10-aace-024f19a55569" }, + //"Serilog": { + // "MinimumLevel": { + // "Default": "Debug", + // "Override": { + // "Microsoft": "Debug", + // "Microsoft.Hosting.Lifetime": "Information", + // "Microsoft.AspNetCore.Authentication": "Debug", + // "System": "Debug" + // } + // } + //}, "Serilog": { - "Using": [ "Serilog.Sinks.Console" ], + "Using": [ "Serilog.Sinks.ApplicationInsights" ], "MinimumLevel": { "Default": "Debug", "Override": { "Microsoft": "Debug", - "Microsoft.EntityFrameworkCore": "Warning", "System": "Debug" } }, "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ], "WriteTo": [ { - "Name": "Console", + "Name": "ApplicationInsights", "Args": { - "theme": "Serilog.Sinks.SystemConsole.Themes.AnsiConsoleTheme::Code, Serilog.Sinks.Console", - "outputTemplate": "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj} ({SourceContext}){NewLine}{Exception}" + "telemetryConverter": "Serilog.Sinks.ApplicationInsights.TelemetryConverters.TraceTelemetryConverter, Serilog.Sinks.ApplicationInsights" } }, { "Name": "File", "Args": { - "path": "../_logs-ApiWithMutlipleApis.txt", + "path": "../../LogFiles/_logs-ApiWithMutlipleApis.txt", "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] [{SourceContext}] [{EventId}] {Message}{NewLine}{Exception}", "rollOnFileSizeLimit": true, "fileSizeLimitBytes": 4194304, diff --git a/AngularMicrosoftEntraIDMultipleApis/ServiceApi/Controllers/ApiForServiceDataController.cs b/AngularMicrosoftEntraIDMultipleApis/ServiceApi/Controllers/ApiForServiceDataController.cs index 8014f9b..9b2f3ec 100644 --- a/AngularMicrosoftEntraIDMultipleApis/ServiceApi/Controllers/ApiForServiceDataController.cs +++ b/AngularMicrosoftEntraIDMultipleApis/ServiceApi/Controllers/ApiForServiceDataController.cs @@ -1,9 +1,9 @@ -using System.Collections.Generic; -using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Swashbuckle.AspNetCore.Annotations; +using System.Collections.Generic; namespace ServiceApi.Controllers; diff --git a/AngularMicrosoftEntraIDMultipleApis/ServiceApi/Policies/HasServiceApiRoleHandler.cs b/AngularMicrosoftEntraIDMultipleApis/ServiceApi/Policies/HasServiceApiRoleHandler.cs index e3839fb..9d60b5d 100644 --- a/AngularMicrosoftEntraIDMultipleApis/ServiceApi/Policies/HasServiceApiRoleHandler.cs +++ b/AngularMicrosoftEntraIDMultipleApis/ServiceApi/Policies/HasServiceApiRoleHandler.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; namespace ServiceApi; - + public class HasServiceApiRoleHandler : AuthorizationHandler { protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, HasServiceApiRoleRequirement requirement) @@ -18,6 +18,12 @@ protected override Task HandleRequirementAsync(AuthorizationHandlerContext conte var roleClaims = context.User.Claims.Where(t => t.Type == "roles"); + // MS namespace: http://schemas.microsoft.com/ws/2008/06/identity/claims/role + if (!roleClaims.Any()) + { + roleClaims = context.User.Claims.Where(t => t.Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/role"); + } + if (roleClaims != null && HasServiceApiRole(roleClaims)) { context.Succeed(requirement); diff --git a/AngularMicrosoftEntraIDMultipleApis/ServiceApi/Program.cs b/AngularMicrosoftEntraIDMultipleApis/ServiceApi/Program.cs index 773fa7f..2872e29 100644 --- a/AngularMicrosoftEntraIDMultipleApis/ServiceApi/Program.cs +++ b/AngularMicrosoftEntraIDMultipleApis/ServiceApi/Program.cs @@ -1,42 +1,20 @@ -using ServiceApi; -using Azure.Identity; -using Serilog; using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; +using Serilog; +using ServiceApi; using System; Log.Logger = new LoggerConfiguration() .WriteTo.Console() - .WriteTo.AzureApp() .CreateBootstrapLogger(); +Log.Information("Starting ServiceApi application"); + try { - Log.Information("Starting WebApi"); - var builder = WebApplication.CreateBuilder(args); - builder.WebHost - .ConfigureKestrel(serverOptions => { serverOptions.AddServerHeader = false; }) - .ConfigureAppConfiguration((context, configurationBuilder) => - { - var config = configurationBuilder.Build(); - var azureKeyVaultEndpoint = config["AzureKeyVaultEndpoint"]; - if (!string.IsNullOrEmpty(azureKeyVaultEndpoint)) - { - // Add Secrets from KeyVault - Log.Information("Use secrets from {AzureKeyVaultEndpoint}", azureKeyVaultEndpoint); - configurationBuilder.AddAzureKeyVault(new Uri(azureKeyVaultEndpoint), new DefaultAzureCredential()); - } - else - { - // Add Secrets from UserSecrets for local development - configurationBuilder.AddUserSecrets("9f17b08c-435a-4f50-ba7a-802e68ca8d80"); - } - }); - builder.Host.UseSerilog((context, loggerConfiguration) => loggerConfiguration + .WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}") .ReadFrom.Configuration(context.Configuration)); var app = builder @@ -45,8 +23,7 @@ app.Run(); } -catch (Exception ex) when (ex.GetType().Name is not "StopTheHostException" - && ex.GetType().Name is not "HostAbortedException") +catch (Exception ex) when (ex.GetType().Name is not "StopTheHostException" && ex.GetType().Name is not "HostAbortedException") { Log.Fatal(ex, "Unhandled exception"); } @@ -54,4 +31,4 @@ { Log.Information("Shut down complete"); Log.CloseAndFlush(); -} +} \ No newline at end of file diff --git a/AngularMicrosoftEntraIDMultipleApis/ServiceApi/ServiceApi.csproj b/AngularMicrosoftEntraIDMultipleApis/ServiceApi/ServiceApi.csproj index 365b465..5c430e3 100644 --- a/AngularMicrosoftEntraIDMultipleApis/ServiceApi/ServiceApi.csproj +++ b/AngularMicrosoftEntraIDMultipleApis/ServiceApi/ServiceApi.csproj @@ -1,30 +1,28 @@  - net8.0 + net9.0 196b270c-b0c0-4b90-8f04-d3108e701d51 enable - + - - - - + + + + - - - - - - - - + + + + + + + + - - diff --git a/AngularMicrosoftEntraIDMultipleApis/ServiceApi/HostingExtensions.cs b/AngularMicrosoftEntraIDMultipleApis/ServiceApi/StartupExtensions.cs similarity index 96% rename from AngularMicrosoftEntraIDMultipleApis/ServiceApi/HostingExtensions.cs rename to AngularMicrosoftEntraIDMultipleApis/ServiceApi/StartupExtensions.cs index c5179cc..5243373 100644 --- a/AngularMicrosoftEntraIDMultipleApis/ServiceApi/HostingExtensions.cs +++ b/AngularMicrosoftEntraIDMultipleApis/ServiceApi/StartupExtensions.cs @@ -4,15 +4,15 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Identity.Web; +using Microsoft.IdentityModel.JsonWebTokens; using Microsoft.IdentityModel.Logging; using Microsoft.OpenApi.Models; using Serilog; using System; -using System.IdentityModel.Tokens.Jwt; namespace ServiceApi; -internal static class HostingExtensions +internal static class StartupExtensions { public static WebApplication ConfigureServices(this WebApplicationBuilder builder) { @@ -85,11 +85,11 @@ public static WebApplication ConfigureServices(this WebApplicationBuilder builde return builder.Build(); } - + public static WebApplication ConfigurePipeline(this WebApplication app) { IdentityModelEventSource.ShowPII = true; - JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); + JsonWebTokenHandler.DefaultInboundClaimTypeMap.Clear(); app.UseSerilogRequestLogging(); diff --git a/AngularMicrosoftEntraIDMultipleApis/ServiceApi/appsettings.json b/AngularMicrosoftEntraIDMultipleApis/ServiceApi/appsettings.json index a1030f4..ac2bb76 100644 --- a/AngularMicrosoftEntraIDMultipleApis/ServiceApi/appsettings.json +++ b/AngularMicrosoftEntraIDMultipleApis/ServiceApi/appsettings.json @@ -5,29 +5,38 @@ "TenantId": "7ff95b15-dc21-4ba6-bc92-824856578fc1", "ClientId": "b178f3a5-7588-492a-924f-72d7887b7e48" }, + //"Serilog": { + // "MinimumLevel": { + // "Default": "Debug", + // "Override": { + // "Microsoft": "Debug", + // "Microsoft.Hosting.Lifetime": "Information", + // "Microsoft.AspNetCore.Authentication": "Debug", + // "System": "Debug" + // } + // } + //}, "Serilog": { - "Using": [ "Serilog.Sinks.Console" ], + "Using": [ "Serilog.Sinks.ApplicationInsights" ], "MinimumLevel": { "Default": "Debug", "Override": { "Microsoft": "Debug", - "Microsoft.EntityFrameworkCore": "Warning", "System": "Debug" } }, "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ], "WriteTo": [ { - "Name": "Console", + "Name": "ApplicationInsights", "Args": { - "theme": "Serilog.Sinks.SystemConsole.Themes.AnsiConsoleTheme::Code, Serilog.Sinks.Console", - "outputTemplate": "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj} ({SourceContext}){NewLine}{Exception}" + "telemetryConverter": "Serilog.Sinks.ApplicationInsights.TelemetryConverters.TraceTelemetryConverter, Serilog.Sinks.ApplicationInsights" } }, { "Name": "File", "Args": { - "path": "../_logs-ServiceApi.txt", + "path": "../../LogFiles/_logs-ServiceApi.txt", "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] [{SourceContext}] [{EventId}] {Message}{NewLine}{Exception}", "rollOnFileSizeLimit": true, "fileSizeLimitBytes": 4194304, diff --git a/AngularMicrosoftEntraIDMultipleApis/UserApi/Controllers/ApiForUserDataController.cs b/AngularMicrosoftEntraIDMultipleApis/UserApi/Controllers/ApiForUserDataController.cs index cd13850..2a3138d 100644 --- a/AngularMicrosoftEntraIDMultipleApis/UserApi/Controllers/ApiForUserDataController.cs +++ b/AngularMicrosoftEntraIDMultipleApis/UserApi/Controllers/ApiForUserDataController.cs @@ -2,7 +2,7 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; -namespace UserApiOne.Controllers; +namespace UserApi.Controllers; [Authorize(Policy = "ValidateAccessTokenPolicy", AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] [ApiController] diff --git a/AngularMicrosoftEntraIDMultipleApis/UserApi/Program.cs b/AngularMicrosoftEntraIDMultipleApis/UserApi/Program.cs index 6fb33e3..5e2ab96 100644 --- a/AngularMicrosoftEntraIDMultipleApis/UserApi/Program.cs +++ b/AngularMicrosoftEntraIDMultipleApis/UserApi/Program.cs @@ -77,7 +77,6 @@ JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); IdentityModelEventSource.ShowPII = true; -JwtSecurityTokenHandler.DefaultMapInboundClaims = false; if (app.Environment.IsDevelopment()) { diff --git a/AngularMicrosoftEntraIDMultipleApis/UserApi/UserApi.csproj b/AngularMicrosoftEntraIDMultipleApis/UserApi/UserApi.csproj index 82a411a..625492f 100644 --- a/AngularMicrosoftEntraIDMultipleApis/UserApi/UserApi.csproj +++ b/AngularMicrosoftEntraIDMultipleApis/UserApi/UserApi.csproj @@ -1,15 +1,22 @@  - net8.0 + net9.0 aspnet-UserApiOne-2ba0bbf9-49f5-452e-8333-1e33a467b74e enable enable - - + + + + + + + + + diff --git a/README.md b/README.md index 09680f3..520ee3e 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ ## History +- 2025-01-02 .NET 9 - 2024-04-11 Updated packages - 2023-12-01 Updated .NET 8 - 2023-08-14 Updated downstream APIs solution