Skip to content

Commit 2c7bbfb

Browse files
Merge branch 'main' into dependabot/nuget/Microsoft.AspNetCore.Authentication.OpenIdConnect-10.0.11
2 parents fe8ca94 + ac6f546 commit 2c7bbfb

26 files changed

Lines changed: 419 additions & 70 deletions

.github/workflows/build.yml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Build
1+
name: Web Build and Deploy
22

33
on:
44
workflow_dispatch:
@@ -15,6 +15,8 @@ env:
1515
WEB_SOLUTION_FILE: SchoolAccount.Web.slnx
1616
MAIN_BRANCH: refs/heads/main
1717
IMAGE_NAME: ghcr.io/dfe-digital/schoolaccount-web
18+
CONTAINERAPP_RESOURCE_GROUP: s268d01rg-uks-sa-poc
19+
CONTAINERAPP_NAME: schoolaccount-web-app
1820

1921
jobs:
2022
build:
@@ -108,3 +110,17 @@ jobs:
108110

109111
- name: Publish
110112
run: dotnet publish ${{ env.WEB_SOLUTION_FILE }} --configuration Release --no-restore --no-build
113+
114+
- name: Azure Login
115+
if: github.event_name == 'push' && github.ref == env.MAIN_BRANCH
116+
uses: azure/login@v2
117+
with:
118+
creds: ${{ secrets.AZURE_CREDENTIALS }}
119+
120+
- name: Update ACA Image
121+
if: github.event_name == 'push' && github.ref == env.MAIN_BRANCH
122+
run: |
123+
az containerapp update \
124+
--name ${{ env.CONTAINERAPP_NAME }} \
125+
--resource-group ${{ env.CONTAINERAPP_RESOURCE_GROUP }} \
126+
--image ${{ steps.image.outputs.image }}

Directory.Packages.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
<PackageVersion Include="Shouldly" Version="4.3.0" />
3333
<PackageVersion Include="NetArchTest.Rules" Version="1.3.2" />
3434
<PackageVersion Include="xunit.v3.mtp-v2" Version="3.2.2" />
35-
<PackageVersion Include="Microsoft.Testing.Extensions.CodeCoverage" Version="18.9.0" />
35+
<PackageVersion Include="Microsoft.Testing.Extensions.CodeCoverage" Version="18.10.0" />
3636
<!-- Experimental (alpha): GitHub Actions job summaries and PR annotations for test runs -->
3737
<PackageVersion Include="Microsoft.Testing.Extensions.GitHubActionsReport" Version="1.0.0-alpha.26377.5" />
3838
<PackageVersion Include="Microsoft.Testing.Extensions.TrxReport" Version="2.3.3" />

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ The image is created on every push to the `main` branch and tagged with the curr
164164

165165
To verify the image locally, you can run:
166166
```
167-
docker run --platform linux/amd64 --name web -e OpenIDConnectSettings__ClientId=SA_TEST_CLIENT -e OpenIDConnectSettings__Authority=https://localhost:7041 -p 5100:8080 -d ghcr.io/dfe-digital/schoolaccount-web:latest
167+
docker run --platform linux/amd64 --name web -e OpenIDConnectSettings__ClientId=SA_TEST_CLIENT -e OpenIDConnectSettings__Authority=https://localhost:7041 -e ASPNETCORE_ENVIRONMENT=development -p 5100:8080 -d --pull=always ghcr.io/dfe-digital/schoolaccount-web:latest
168168
```
169169

170170
You can then test the Web project by visiting http://localhost:5100.

src/SchoolAccount.SharedKernel/IUserContext.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ public interface IUserContext
77
string? AuthenticationType { get; }
88
string? EmailAddress { get; }
99
string? Name { get; }
10+
string? OrganisationName { get; }
1011
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace SchoolAccount.Web.Mvc.Authentication;
2+
3+
public static class ClaimConstants
4+
{
5+
public const string Id = "sid";
6+
public const string GivenName = "given_name";
7+
public const string FamilyName = "family_name";
8+
public const string Email = "email";
9+
public const string Organisation = "organisation";
10+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using System.Security.Claims;
2+
using System.Text.Json;
3+
4+
namespace SchoolAccount.Web.Mvc.Authentication.Extensions;
5+
6+
public static class ClaimsPrincipalExtensions
7+
{
8+
public static OrganisationClaim? GetOrganisation(
9+
this ClaimsPrincipal principal,
10+
JsonSerializerOptions? options = null
11+
)
12+
{
13+
options ??= new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
14+
var organisationClaim = principal.FindFirst(ClaimConstants.Organisation)?.Value;
15+
return !string.IsNullOrEmpty(organisationClaim)
16+
? JsonSerializer.Deserialize<OrganisationClaim>(organisationClaim, options)
17+
: null;
18+
}
19+
}

src/SchoolAccount.Web.Mvc/Authentication/Extensions/ServiceCollectionExtensions.cs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
using System.Diagnostics.CodeAnalysis;
21
using Microsoft.AspNetCore.Authentication.Cookies;
32
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
4-
using Microsoft.AspNetCore.Authorization;
53
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
64
using SchoolAccount.SharedKernel;
75
using SchoolAccount.Web.Mvc.Authentication.Models;
6+
using static SchoolAccount.Web.Mvc.Authentication.ClaimConstants;
87

98
namespace SchoolAccount.Web.Mvc.Authentication.Extensions;
109

@@ -40,8 +39,8 @@ IConfigurationManager configuration
4039
options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
4140
options.ResponseType = OpenIdConnectResponseType.IdToken;
4241

43-
options.Scope.Add("organisation");
44-
options.Scope.Add("email");
42+
options.Scope.Add(Organisation);
43+
options.Scope.Add(Email);
4544
options.SaveTokens = true;
4645
options.GetClaimsFromUserInfoEndpoint = true;
4746

@@ -54,6 +53,17 @@ IConfigurationManager configuration
5453
context.HttpContext.Session.Clear();
5554
await Task.CompletedTask;
5655
},
56+
// within ACA a container runs on http, though available as https publicly
57+
// this causes the OIDC redirect_url to have the http protocol, rather than https
58+
// DSI does not allow http redirect URLS. The following corrects the URL
59+
OnRedirectToIdentityProvider = async n =>
60+
{
61+
n.ProtocolMessage.RedirectUri = n.ProtocolMessage.RedirectUri.Replace(
62+
"http://",
63+
"https://"
64+
);
65+
await Task.CompletedTask;
66+
},
5767
};
5868
});
5969

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace SchoolAccount.Web.Mvc.Authentication;
2+
3+
public record OrganisationClaim
4+
{
5+
public string Name { get; init; } = null!;
6+
}
Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Security.Principal;
22
using SchoolAccount.SharedKernel;
3+
using SchoolAccount.Web.Mvc.Authentication.Extensions;
34

45
namespace SchoolAccount.Web.Mvc.Authentication;
56

@@ -9,19 +10,21 @@ public UserContext(IHttpContextAccessor contextAccessor)
910
{
1011
var user = contextAccessor.HttpContext?.User;
1112
IsAuthenticated = user?.Identity?.IsAuthenticated ?? false;
12-
Id = user?.FindFirst("sid")?.Value;
13+
Id = user?.FindFirst(ClaimConstants.Id)?.Value;
1314
AuthenticationType = user?.Identity?.AuthenticationType;
14-
GivenName = user?.FindFirst("given_name")?.Value;
15-
Surname = user?.FindFirst("family_name")?.Value;
16-
EmailAddress = user?.FindFirst("email")?.Value;
15+
GivenName = user?.FindFirst(ClaimConstants.GivenName)?.Value;
16+
Surname = user?.FindFirst(ClaimConstants.FamilyName)?.Value;
17+
EmailAddress = user?.FindFirst(ClaimConstants.Email)?.Value;
18+
OrganisationName = user?.GetOrganisation()?.Name;
1719
}
1820

1921
public string? GivenName { get; }
2022
public string? Surname { get; }
21-
2223
public bool IsAuthenticated { get; }
2324
public string? Id { get; }
2425
public string? AuthenticationType { get; }
2526
public string? Name => $"{GivenName} {Surname}".Trim();
2627
public string? EmailAddress { get; }
28+
29+
public string? OrganisationName { get; }
2730
}
Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using System.Diagnostics.CodeAnalysis;
21
using Microsoft.AspNetCore.Authorization;
32
using Microsoft.AspNetCore.Mvc;
43

@@ -7,14 +6,10 @@ namespace SchoolAccount.Web.Mvc.Features.Home;
76
[Route("/")]
87
public class HomeController : Controller
98
{
10-
[HttpGet(""), AllowAnonymous]
9+
[HttpGet("")]
10+
[AllowAnonymous]
1111
public async Task<IActionResult> Home()
1212
{
13-
if (User.Identity?.IsAuthenticated ?? false)
14-
{
15-
return RedirectToAction("Dashboard", "Dashboard");
16-
}
17-
1813
return View(new HomeViewModel());
1914
}
2015
}

0 commit comments

Comments
 (0)