diff --git a/.github/workflows/azure-deploy-issuer-employee.yml b/.github/workflows/azure-deploy-issuer-employee.yml index 044a9a6..9a791a3 100644 --- a/.github/workflows/azure-deploy-issuer-employee.yml +++ b/.github/workflows/azure-deploy-issuer-employee.yml @@ -22,7 +22,7 @@ name: Build and deploy ASP.Net Core app to an Azure Web App env: AZURE_WEBAPP_NAME: IssueVerifiableEmployee # set this to the name of your Azure Web App AZURE_WEBAPP_PACKAGE_PATH: '.' # set this to the path to your web app project, defaults to the repository root - DOTNET_VERSION: '8.0' # set this to the .NET Core version to use + DOTNET_VERSION: '9.0' # set this to the .NET Core version to use on: push: diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 98b2ab6..0b8435c 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -17,7 +17,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v4 with: - dotnet-version: 8.0.x + dotnet-version: 9.0.x - name: Restore dependencies run: dotnet restore - name: Build diff --git a/IssueVerifiableEmployee/IssueVerifiableEmployee.csproj b/IssueVerifiableEmployee/IssueVerifiableEmployee.csproj index 3a3e30a..696d3b4 100644 --- a/IssueVerifiableEmployee/IssueVerifiableEmployee.csproj +++ b/IssueVerifiableEmployee/IssueVerifiableEmployee.csproj @@ -1,23 +1,23 @@  - net8.0 + net9.0 enable enable d0874390-bd6a-4cde-a360-b9733de66c7c - - - - - - - - - - + + + + + + + + + + diff --git a/IssueVerifiableEmployee/Program.cs b/IssueVerifiableEmployee/Program.cs index c4f5121..45c5146 100644 --- a/IssueVerifiableEmployee/Program.cs +++ b/IssueVerifiableEmployee/Program.cs @@ -22,6 +22,10 @@ options.AllowSynchronousIO = true; }); +services.AddSecurityHeaderPolicies() + .SetPolicySelector(ctx => SecurityHeadersDefinitions + .GetHeaderPolicyCollection(builder.Environment.IsDevelopment())); + services.Configure(configuration.GetSection("CredentialSettings")); services.AddScoped(); services.AddScoped(); @@ -59,9 +63,7 @@ var app = builder.Build(); -app.UseSecurityHeaders(SecurityHeadersDefinitions - .GetHeaderPolicyCollection(app.Environment.IsDevelopment())); - +app.UseSecurityHeaders(); if (app.Environment.IsDevelopment()) { diff --git a/IssueVerifiableEmployee/SecurityHeadersDefinitions.cs b/IssueVerifiableEmployee/SecurityHeadersDefinitions.cs index e5c41e7..700a46c 100644 --- a/IssueVerifiableEmployee/SecurityHeadersDefinitions.cs +++ b/IssueVerifiableEmployee/SecurityHeadersDefinitions.cs @@ -2,11 +2,19 @@ namespace IssuerVerifiableEmployee; public static class SecurityHeadersDefinitions { + private static HeaderPolicyCollection? policy; + public static HeaderPolicyCollection GetHeaderPolicyCollection(bool isDev) { - var policy = new HeaderPolicyCollection() + // Avoid building a new HeaderPolicyCollection on every request for performance reasons. + // Where possible, cache and reuse HeaderPolicyCollection instances. + if (policy != null) + { + return policy; + } + + policy = new HeaderPolicyCollection() .AddFrameOptionsDeny() - .AddXssProtectionBlock() .AddContentTypeOptionsNoSniff() .AddReferrerPolicyStrictOriginWhenCrossOrigin() .AddCrossOriginOpenerPolicy(builder => builder.SameOrigin()) @@ -26,23 +34,7 @@ public static HeaderPolicyCollection GetHeaderPolicyCollection(bool isDev) //builder.AddCustomDirective("require-trusted-types-for", "'script'"); }) .RemoveServerHeader() - .AddPermissionsPolicy(builder => - { - builder.AddAccelerometer().None(); - builder.AddAutoplay().None(); - builder.AddCamera().None(); - builder.AddEncryptedMedia().None(); - builder.AddFullscreen().All(); - builder.AddGeolocation().None(); - builder.AddGyroscope().None(); - builder.AddMagnetometer().None(); - builder.AddMicrophone().None(); - builder.AddMidi().None(); - builder.AddPayment().None(); - builder.AddPictureInPicture().None(); - builder.AddSyncXHR().None(); - builder.AddUsb().None(); - }); + .AddPermissionsPolicyWithDefaultSecureDirectives(); if (!isDev) { @@ -50,8 +42,6 @@ public static HeaderPolicyCollection GetHeaderPolicyCollection(bool isDev) policy.AddStrictTransportSecurityMaxAgeIncludeSubDomains(maxAgeInSeconds: 60 * 60 * 24 * 365); } - policy.ApplyDocumentHeadersToAllResponses(); - return policy; } } diff --git a/IssueVerifiableEmployee/Services/IssuerController.cs b/IssueVerifiableEmployee/Services/IssuerController.cs index cc2829d..a62ca83 100644 --- a/IssueVerifiableEmployee/Services/IssuerController.cs +++ b/IssueVerifiableEmployee/Services/IssuerController.cs @@ -58,12 +58,12 @@ public async Task IssuanceRequestAsync() var res = await _httpClient.PostAsJsonAsync(_credentialSettings.Endpoint, payload); - if(!res.IsSuccessStatusCode) + if (!res.IsSuccessStatusCode) { var test = await res.Content.ReadAsStringAsync(); _log.LogError("failed to acquire access token: {Error}", test); } - + var response = await res.Content.ReadFromJsonAsync(); if (response == null) diff --git a/README.md b/README.md index 776c640..b99cff4 100644 --- a/README.md +++ b/README.md @@ -4,15 +4,16 @@ [Issue Employee verifiable credentials using Entra Verified ID and ASP.NET Core](https://damienbod.com/2023/07/03/issue-employee-verifiable-credentials-using-entra-verified-id-and-asp-net-core/) -### History +## History +- 2024-12-12 .NET 9, update packages - 2024-09-13 Update packages - 2024-03-09 Update packages - 2023-12-02 .NET 8, fix Graph stream handling - 2023-07-28 Add Magick.NET for photo conversion - 2023-07-27 Updated packages -### Local debugging, required for callback +## Local debugging, required for callback Note: the public URL needs to be added to the redirct_url settings in the Azure App registration. @@ -20,7 +21,7 @@ Note: the public URL needs to be added to the redirct_url settings in the Azure ngrok http https://localhost:5001 ``` -### Verified Employee scheme +## Verified Employee scheme ```csharp public class CredentialsClaims @@ -44,7 +45,7 @@ public class CredentialsClaims } ``` -### Update the preferredLanguage +## Update the preferredLanguage PATCH @@ -56,7 +57,7 @@ https://graph.microsoft.com/v1.0/users/{oid} } ``` -### Photo with a license +## Photo with a license https://portal.office.com/account/?ref=MeControl#personalinfo @@ -64,7 +65,7 @@ https://learn.microsoft.com/en-us/graph/api/profilephoto-update?view=graph-rest- https://graph.microsoft.com/v1.0/users/{oid}/photo -### Photo +## Photo You can update the profile photo in the Azure AD portal without a license in the users basic profile settings.