-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
28 changed files
with
965 additions
and
180 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 31 additions & 0 deletions
31
...m.AuthorizeAccess/Infrastructure/Filters/AssignViewDataFromFormFlowJourneyResultFilter.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
using Microsoft.AspNetCore.Mvc.Filters; | ||
using Microsoft.AspNetCore.Mvc.RazorPages; | ||
using TeachingRecordSystem.AuthorizeAccess.Infrastructure.FormFlow; | ||
using TeachingRecordSystem.FormFlow.State; | ||
|
||
namespace TeachingRecordSystem.AuthorizeAccess.Infrastructure.Filters; | ||
|
||
public class AssignViewDataFromFormFlowJourneyResultFilter(IUserInstanceStateProvider stateProvider, AuthorizeAccessLinkGenerator linkGenerator) : IAsyncResultFilter | ||
{ | ||
public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next) | ||
{ | ||
var journeyInstance = await stateProvider.GetSignInJourneyInstanceAsync(context.HttpContext); | ||
|
||
if (journeyInstance is not null && context.Result is PageResult pageResult) | ||
{ | ||
pageResult.ViewData.Add("ServiceName", journeyInstance.State.ServiceName); | ||
pageResult.ViewData.Add("ServiceUrl", journeyInstance.State.ServiceUrl); | ||
pageResult.ViewData.Add("SignOutLink", linkGenerator.SignOut(journeyInstance.InstanceId)); | ||
} | ||
|
||
await next(); | ||
} | ||
} | ||
|
||
public class AssignViewDataFromFormFlowJourneyResultFilterFactory : IFilterFactory | ||
{ | ||
public bool IsReusable => false; | ||
|
||
public IFilterMetadata CreateInstance(IServiceProvider serviceProvider) => | ||
ActivatorUtilities.CreateInstance<AssignViewDataFromFormFlowJourneyResultFilter>(serviceProvider); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
29 changes: 29 additions & 0 deletions
29
TeachingRecordSystem/src/TeachingRecordSystem.AuthorizeAccess/Pages/Oidc/SignOut.cshtml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
@page "/connect/logout" | ||
@using Microsoft.AspNetCore.Http.Extensions | ||
@using Microsoft.Extensions.Primitives | ||
@using TeachingRecordSystem.AuthorizeAccess.Pages.Oidc | ||
@addTagHelper *, Joonasw.AspNetCore.SecurityHeaders | ||
@model SignOutModel | ||
@{ | ||
ViewBag.Title = $"Sign out of {Model.ServiceName}"; | ||
ViewBag.ServiceName = Model.ServiceName; | ||
ViewBag.ServiceUrl = Model.ServiceUrl; | ||
ViewBag.SignOutLink = Request.GetEncodedUrl(); | ||
} | ||
|
||
<form asp-page="SignOut" method="post"> | ||
<div class="govuk-grid-row"> | ||
<div class="govuk-grid-column-two-thirds-from-desktop"> | ||
<h1 class="govuk-heading-l">@ViewBag.Title</h1> | ||
|
||
@foreach (var parameter in HttpContext.Request.HasFormContentType ? (IEnumerable<KeyValuePair<string, StringValues>>)HttpContext.Request.Form : HttpContext.Request.Query) | ||
{ | ||
<input type="hidden" name="@parameter.Key" value="@parameter.Value" /> | ||
} | ||
|
||
<govuk-button type="submit">Sign out</govuk-button> | ||
</div> | ||
</div> | ||
</form> | ||
|
||
<script asp-add-nonce="true">document.forms[0].submit();</script> |
73 changes: 73 additions & 0 deletions
73
TeachingRecordSystem/src/TeachingRecordSystem.AuthorizeAccess/Pages/Oidc/SignOut.cshtml.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
using System.Security.Claims; | ||
using Microsoft.AspNetCore; | ||
using Microsoft.AspNetCore.Authentication; | ||
using Microsoft.AspNetCore.Mvc; | ||
using Microsoft.AspNetCore.Mvc.Filters; | ||
using Microsoft.AspNetCore.Mvc.RazorPages; | ||
using Microsoft.IdentityModel.Protocols.OpenIdConnect; | ||
using OpenIddict.Abstractions; | ||
using OpenIddict.Server.AspNetCore; | ||
using TeachingRecordSystem.Core.DataStore.Postgres; | ||
using TeachingRecordSystem.Core.DataStore.Postgres.Models; | ||
|
||
namespace TeachingRecordSystem.AuthorizeAccess.Pages.Oidc; | ||
|
||
public class SignOutModel(TrsDbContext dbContext) : PageModel | ||
{ | ||
private OpenIddictRequest? _request; | ||
private AuthenticateResult? _authenticateResult; | ||
private ApplicationUser? _client; | ||
|
||
public string ServiceName => _client!.Name; | ||
public string ServiceUrl => new Uri(_request!.PostLogoutRedirectUri!).GetLeftPart(UriPartial.Authority); | ||
|
||
public void OnGet() | ||
{ | ||
} | ||
|
||
public async Task<IActionResult> OnPost() | ||
{ | ||
// We need to sign out with One Login and then complete the OIDC sign out request. | ||
// We do it by calling SignOutAsync with OpenIddict first, capturing the Location header from its redirect | ||
// then redirecting to OneLogin with that URL as the RedirectUri. | ||
|
||
await HttpContext.SignOutAsync( | ||
OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, | ||
new AuthenticationProperties() | ||
{ | ||
RedirectUri = "/" | ||
}); | ||
|
||
var authenticationProperties = new AuthenticationProperties() | ||
{ | ||
RedirectUri = HttpContext.Response.Headers.Location | ||
}; | ||
var oneLoginIdToken = _authenticateResult!.Principal!.FindFirstValue(ClaimTypes.OneLoginIdToken)!; | ||
authenticationProperties.SetParameter(OpenIdConnectParameterNames.IdToken, oneLoginIdToken); | ||
|
||
return SignOut(authenticationProperties, _client!.OneLoginAuthenticationSchemeName!); | ||
} | ||
|
||
public async override Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next) | ||
{ | ||
// Although the spec allows for logout requests without an id_token_hint, we require one so we can | ||
// a) extract the One Login ID token and; | ||
// b) know which authentication scheme to sign out with. | ||
|
||
_request = HttpContext.GetOpenIddictServerRequest() ?? | ||
throw new InvalidOperationException("The OpenID Connect request cannot be retrieved."); | ||
|
||
if (_request.IdTokenHint is null) | ||
{ | ||
context.Result = BadRequest(); | ||
return; | ||
} | ||
|
||
_authenticateResult = await HttpContext.AuthenticateAsync(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme); | ||
|
||
string clientId = _authenticateResult.Principal!.GetAudiences().Single(); | ||
_client = await dbContext.ApplicationUsers.SingleAsync(u => u.ClientId == clientId); | ||
|
||
await base.OnPageHandlerExecutionAsync(context, next); | ||
} | ||
} |
93 changes: 71 additions & 22 deletions
93
TeachingRecordSystem/src/TeachingRecordSystem.AuthorizeAccess/Pages/OidcTest/_Layout.cshtml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,33 +1,82 @@ | ||
@{ | ||
Layout = "../Shared/_Layout"; | ||
|
||
ViewBag.ServiceName = "OIDC Sample"; | ||
Layout = "_GovUkPageTemplate"; | ||
} | ||
|
||
@section Styles { | ||
@section Head { | ||
<meta name="robots" content="noindex"> | ||
<link rel="stylesheet" asp-href-include="~/Styles/*.css"> | ||
@RenderSection("Styles", required: false) | ||
@RenderSection("Scripts", required: false) | ||
} | ||
|
||
@section Scripts { | ||
@RenderSection("Scripts", required: false) | ||
@section Header { | ||
<header class="govuk-header" role="banner" data-module="govuk-header"> | ||
<div class="govuk-header__container govuk-width-container"> | ||
<div class="govuk-header__logo"> | ||
<a href="#" class="govuk-header__link govuk-header__link--homepage"> | ||
<span class="govuk-header__logotype"> | ||
<!--[if gt IE 8]><!--> | ||
<svg aria-hidden="true" | ||
focusable="false" | ||
class="govuk-header__logotype-crown" | ||
xmlns="http://www.w3.org/2000/svg" | ||
viewBox="0 0 32 30" | ||
height="30" | ||
width="32"> | ||
<path fill="currentColor" fill-rule="evenodd" | ||
d="M22.6 10.4c-1 .4-2-.1-2.4-1-.4-.9.1-2 1-2.4.9-.4 2 .1 2.4 1s-.1 2-1 2.4m-5.9 6.7c-.9.4-2-.1-2.4-1-.4-.9.1-2 1-2.4.9-.4 2 .1 2.4 1s-.1 2-1 2.4m10.8-3.7c-1 .4-2-.1-2.4-1-.4-.9.1-2 1-2.4.9-.4 2 .1 2.4 1s0 2-1 2.4m3.3 4.8c-1 .4-2-.1-2.4-1-.4-.9.1-2 1-2.4.9-.4 2 .1 2.4 1s-.1 2-1 2.4M17 4.7l2.3 1.2V2.5l-2.3.7-.2-.2.9-3h-3.4l.9 3-.2.2c-.1.1-2.3-.7-2.3-.7v3.4L15 4.7c.1.1.1.2.2.2l-1.3 4c-.1.2-.1.4-.1.6 0 1.1.8 2 1.9 2.2h.7c1-.2 1.9-1.1 1.9-2.1 0-.2 0-.4-.1-.6l-1.3-4c-.1-.2 0-.2.1-.3m-7.6 5.7c.9.4 2-.1 2.4-1 .4-.9-.1-2-1-2.4-.9-.4-2 .1-2.4 1s0 2 1 2.4m-5 3c.9.4 2-.1 2.4-1 .4-.9-.1-2-1-2.4-.9-.4-2 .1-2.4 1s.1 2 1 2.4m-3.2 4.8c.9.4 2-.1 2.4-1 .4-.9-.1-2-1-2.4-.9-.4-2 .1-2.4 1s0 2 1 2.4m14.8 11c4.4 0 8.6.3 12.3.8 1.1-4.5 2.4-7 3.7-8.8l-2.5-.9c.2 1.3.3 1.9 0 2.7-.4-.4-.8-1.1-1.1-2.3l-1.2 4c.7-.5 1.3-.8 2-.9-1.1 2.5-2.6 3.1-3.5 3-1.1-.2-1.7-1.2-1.5-2.1.3-1.2 1.5-1.5 2.1-.1 1.1-2.3-.8-3-2-2.3 1.9-1.9 2.1-3.5.6-5.6-2.1 1.6-2.1 3.2-1.2 5.5-1.2-1.4-3.2-.6-2.5 1.6.9-1.4 2.1-.5 1.9.8-.2 1.1-1.7 2.1-3.5 1.9-2.7-.2-2.9-2.1-2.9-3.6.7-.1 1.9.5 2.9 1.9l.4-4.3c-1.1 1.1-2.1 1.4-3.2 1.4.4-1.2 2.1-3 2.1-3h-5.4s1.7 1.9 2.1 3c-1.1 0-2.1-.2-3.2-1.4l.4 4.3c1-1.4 2.2-2 2.9-1.9-.1 1.5-.2 3.4-2.9 3.6-1.9.2-3.4-.8-3.5-1.9-.2-1.3 1-2.2 1.9-.8.7-2.3-1.2-3-2.5-1.6.9-2.2.9-3.9-1.2-5.5-1.5 2-1.3 3.7.6 5.6-1.2-.7-3.1 0-2 2.3.6-1.4 1.8-1.1 2.1.1.2.9-.3 1.9-1.5 2.1-.9.2-2.4-.5-3.5-3 .6 0 1.2.3 2 .9l-1.2-4c-.3 1.1-.7 1.9-1.1 2.3-.3-.8-.2-1.4 0-2.7l-2.9.9C1.3 23 2.6 25.5 3.7 30c3.7-.5 7.9-.8 12.3-.8"></path> | ||
</svg> | ||
<!--<![endif]--> | ||
<!--[if IE 8]> | ||
<img src="/assets/images/govuk-logotype-tudor-crown.png" class="govuk-header__logotype-crown-fallback-image" width="32" height="30" alt=""> | ||
<![endif]--> | ||
<span class="govuk-header__logotype-text"> | ||
GOV.UK | ||
</span> | ||
</span> | ||
</a> | ||
</div> | ||
<div class="govuk-header__content"> | ||
<a asp-page="/oidc-test" class="govuk-header__link govuk-header__link--service-name"> | ||
OIDC test app | ||
</a> | ||
@if (User.Identity?.IsAuthenticated == true) | ||
{ | ||
<nav aria-label="Menu" class="govuk-header__navigation"> | ||
<button type="button" class="govuk-header__menu-button govuk-js-header-toggle" aria-controls="navigation" hidden> | ||
Menu | ||
</button> | ||
<ul id="navigation" class="govuk-header__navigation-list"> | ||
<li class="govuk-header__navigation-item govuk-header__navigation-item--active"> | ||
<a class="govuk-header__link" asp-page="SignOut"> | ||
Sign out | ||
</a> | ||
</li> | ||
</ul> | ||
</nav> | ||
} | ||
@RenderSection("Nav", required: false) | ||
</div> | ||
</div> | ||
</header> | ||
} | ||
|
||
@if (User.Identity?.IsAuthenticated == true) | ||
{ | ||
@section Nav { | ||
<nav aria-label="Menu" class="govuk-header__navigation"> | ||
<button type="button" class="govuk-header__menu-button govuk-js-header-toggle" aria-controls="navigation" hidden> | ||
Menu | ||
</button> | ||
<ul id="navigation" class="govuk-header__navigation-list"> | ||
<li class="govuk-header__navigation-item govuk-header__navigation-item--active"> | ||
<a class="govuk-header__link" asp-page="SignOut"> | ||
Sign out | ||
</a> | ||
</li> | ||
</ul> | ||
</nav> | ||
} | ||
@section BeforeContent { | ||
@RenderSection("BeforeContent", required: false) | ||
} | ||
|
||
@RenderBody() | ||
|
||
@section Footer { | ||
<footer class="govuk-footer" role="contentinfo"> | ||
<div class="govuk-width-container "> | ||
<div class="govuk-footer__meta"> | ||
<div class="govuk-footer__meta-item govuk-footer__meta-item--grow"> | ||
</div> | ||
<div class="govuk-footer__meta-item"> | ||
<a class="govuk-footer__link govuk-footer__copyright-logo" href="https://www.nationalarchives.gov.uk/information-management/re-using-public-sector-information/uk-government-licensing-framework/crown-copyright/">© Crown copyright</a> | ||
</div> | ||
</div> | ||
</div> | ||
</footer> | ||
} |
1 change: 1 addition & 0 deletions
1
...ingRecordSystem/src/TeachingRecordSystem.AuthorizeAccess/Pages/Shared/GenericError.cshtml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
@{ | ||
Layout = "./ErrorLayout"; | ||
ViewBag.Title = "Sorry, there is a problem with the service"; | ||
} | ||
|
||
|
1 change: 1 addition & 0 deletions
1
TeachingRecordSystem/src/TeachingRecordSystem.AuthorizeAccess/Pages/Shared/NotFound.cshtml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
@{ | ||
Layout = "./ErrorLayout"; | ||
ViewBag.Title = "Page not found"; | ||
} | ||
|
||
|
41 changes: 41 additions & 0 deletions
41
...ingRecordSystem/src/TeachingRecordSystem.AuthorizeAccess/Pages/Shared/_ErrorLayout.cshtml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
@{ | ||
Layout = "./Layout"; | ||
} | ||
|
||
@section Header { | ||
<header class="govuk-header" role="banner" data-module="govuk-header"> | ||
<div class="govuk-header__container govuk-width-container"> | ||
<div class="govuk-header__logo"> | ||
<a href="https://www.gov.uk/" class="govuk-header__link govuk-header__link--homepage"> | ||
<span class="govuk-header__logotype"> | ||
<!--[if gt IE 8]><!--> | ||
<svg aria-hidden="true" | ||
focusable="false" | ||
class="govuk-header__logotype-crown" | ||
xmlns="http://www.w3.org/2000/svg" | ||
viewBox="0 0 32 30" | ||
height="30" | ||
width="32"> | ||
<path fill="currentColor" fill-rule="evenodd" | ||
d="M22.6 10.4c-1 .4-2-.1-2.4-1-.4-.9.1-2 1-2.4.9-.4 2 .1 2.4 1s-.1 2-1 2.4m-5.9 6.7c-.9.4-2-.1-2.4-1-.4-.9.1-2 1-2.4.9-.4 2 .1 2.4 1s-.1 2-1 2.4m10.8-3.7c-1 .4-2-.1-2.4-1-.4-.9.1-2 1-2.4.9-.4 2 .1 2.4 1s0 2-1 2.4m3.3 4.8c-1 .4-2-.1-2.4-1-.4-.9.1-2 1-2.4.9-.4 2 .1 2.4 1s-.1 2-1 2.4M17 4.7l2.3 1.2V2.5l-2.3.7-.2-.2.9-3h-3.4l.9 3-.2.2c-.1.1-2.3-.7-2.3-.7v3.4L15 4.7c.1.1.1.2.2.2l-1.3 4c-.1.2-.1.4-.1.6 0 1.1.8 2 1.9 2.2h.7c1-.2 1.9-1.1 1.9-2.1 0-.2 0-.4-.1-.6l-1.3-4c-.1-.2 0-.2.1-.3m-7.6 5.7c.9.4 2-.1 2.4-1 .4-.9-.1-2-1-2.4-.9-.4-2 .1-2.4 1s0 2 1 2.4m-5 3c.9.4 2-.1 2.4-1 .4-.9-.1-2-1-2.4-.9-.4-2 .1-2.4 1s.1 2 1 2.4m-3.2 4.8c.9.4 2-.1 2.4-1 .4-.9-.1-2-1-2.4-.9-.4-2 .1-2.4 1s0 2 1 2.4m14.8 11c4.4 0 8.6.3 12.3.8 1.1-4.5 2.4-7 3.7-8.8l-2.5-.9c.2 1.3.3 1.9 0 2.7-.4-.4-.8-1.1-1.1-2.3l-1.2 4c.7-.5 1.3-.8 2-.9-1.1 2.5-2.6 3.1-3.5 3-1.1-.2-1.7-1.2-1.5-2.1.3-1.2 1.5-1.5 2.1-.1 1.1-2.3-.8-3-2-2.3 1.9-1.9 2.1-3.5.6-5.6-2.1 1.6-2.1 3.2-1.2 5.5-1.2-1.4-3.2-.6-2.5 1.6.9-1.4 2.1-.5 1.9.8-.2 1.1-1.7 2.1-3.5 1.9-2.7-.2-2.9-2.1-2.9-3.6.7-.1 1.9.5 2.9 1.9l.4-4.3c-1.1 1.1-2.1 1.4-3.2 1.4.4-1.2 2.1-3 2.1-3h-5.4s1.7 1.9 2.1 3c-1.1 0-2.1-.2-3.2-1.4l.4 4.3c1-1.4 2.2-2 2.9-1.9-.1 1.5-.2 3.4-2.9 3.6-1.9.2-3.4-.8-3.5-1.9-.2-1.3 1-2.2 1.9-.8.7-2.3-1.2-3-2.5-1.6.9-2.2.9-3.9-1.2-5.5-1.5 2-1.3 3.7.6 5.6-1.2-.7-3.1 0-2 2.3.6-1.4 1.8-1.1 2.1.1.2.9-.3 1.9-1.5 2.1-.9.2-2.4-.5-3.5-3 .6 0 1.2.3 2 .9l-1.2-4c-.3 1.1-.7 1.9-1.1 2.3-.3-.8-.2-1.4 0-2.7l-2.9.9C1.3 23 2.6 25.5 3.7 30c3.7-.5 7.9-.8 12.3-.8"></path> | ||
</svg> | ||
<!--<![endif]--> | ||
<!--[if IE 8]> | ||
<img src="/assets/images/govuk-logotype-tudor-crown.png" class="govuk-header__logotype-crown-fallback-image" width="32" height="30" alt=""> | ||
<![endif]--> | ||
<span class="govuk-header__logotype-text"> | ||
GOV.UK | ||
</span> | ||
</span> | ||
</a> | ||
</div> | ||
<div class="govuk-header__content"> | ||
<a href="/" class="govuk-header__link govuk-header__link--service-name"> | ||
Authorise access to a teaching record | ||
</a> | ||
</div> | ||
</div> | ||
</header> | ||
} | ||
|
||
@RenderBody() |
Oops, something went wrong.