diff --git a/TeachingRecordSystem/Directory.Packages.props b/TeachingRecordSystem/Directory.Packages.props
index 637abe92a..57d983d27 100644
--- a/TeachingRecordSystem/Directory.Packages.props
+++ b/TeachingRecordSystem/Directory.Packages.props
@@ -42,6 +42,7 @@
+
@@ -91,4 +92,4 @@
-
+
\ No newline at end of file
diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.AuthorizeAccess/Controllers/OAuth2Controller.cs b/TeachingRecordSystem/src/TeachingRecordSystem.AuthorizeAccess/Controllers/OAuth2Controller.cs
index 9e531f71e..38949600a 100644
--- a/TeachingRecordSystem/src/TeachingRecordSystem.AuthorizeAccess/Controllers/OAuth2Controller.cs
+++ b/TeachingRecordSystem/src/TeachingRecordSystem.AuthorizeAccess/Controllers/OAuth2Controller.cs
@@ -48,14 +48,19 @@ public async Task Authorize()
var parameters = Request.HasFormContentType ? Request.Form.ToList() : Request.Query.ToList();
var serviceUrl = new Uri(request.RedirectUri!).GetLeftPart(UriPartial.Authority);
+ var trnToken = parameters.GroupBy(kvp => kvp.Key).FirstOrDefault(kvp => kvp.Key == "trn_token")?.Select(kvp => kvp.Value).FirstOrDefault();
var authenticationProperties = new AuthenticationProperties()
{
- RedirectUri = Request.PathBase + Request.Path + QueryString.Create(parameters)
+ RedirectUri = Request.PathBase + Request.Path + QueryString.Create(parameters),
+ Items =
+ {
+ { MatchToTeachingRecordAuthenticationHandler.AuthenticationPropertiesItemKeys.OneLoginAuthenticationScheme, client.OneLoginAuthenticationSchemeName },
+ { MatchToTeachingRecordAuthenticationHandler.AuthenticationPropertiesItemKeys.ServiceName, client.Name },
+ { MatchToTeachingRecordAuthenticationHandler.AuthenticationPropertiesItemKeys.ServiceUrl, serviceUrl },
+ { MatchToTeachingRecordAuthenticationHandler.AuthenticationPropertiesItemKeys.TrnToken, trnToken },
+ }
};
- authenticationProperties.Items.Add(MatchToTeachingRecordAuthenticationHandler.AuthenticationPropertiesItemKeys.OneLoginAuthenticationScheme, client.OneLoginAuthenticationSchemeName);
- authenticationProperties.Items.Add(MatchToTeachingRecordAuthenticationHandler.AuthenticationPropertiesItemKeys.ServiceName, client.Name);
- authenticationProperties.Items.Add(MatchToTeachingRecordAuthenticationHandler.AuthenticationPropertiesItemKeys.ServiceUrl, serviceUrl);
return Challenge(authenticationProperties, childAuthenticationScheme);
}
diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.AuthorizeAccess/IdDbContext.cs b/TeachingRecordSystem/src/TeachingRecordSystem.AuthorizeAccess/IdDbContext.cs
new file mode 100644
index 000000000..e02b97618
--- /dev/null
+++ b/TeachingRecordSystem/src/TeachingRecordSystem.AuthorizeAccess/IdDbContext.cs
@@ -0,0 +1,30 @@
+using System.ComponentModel.DataAnnotations.Schema;
+
+namespace TeachingRecordSystem.AuthorizeAccess;
+
+public class IdDbContext(DbContextOptions options) : DbContext(options)
+{
+ public DbSet TrnTokens => Set();
+
+ protected override void OnModelCreating(ModelBuilder modelBuilder)
+ {
+ modelBuilder.Entity().HasKey(t => t.TrnToken);
+ }
+}
+
+[Table("trn_tokens")]
+public class IdTrnToken
+{
+ [Column("trn_token")]
+ public required string TrnToken { get; set; }
+ [Column("trn")]
+ public required string Trn { get; set; }
+ [Column("email")]
+ public required string Email { get; set; }
+ [Column("created_utc")]
+ public required DateTime CreatedUtc { get; set; }
+ [Column("expires_utc")]
+ public required DateTime ExpiresUtc { get; set; }
+ [Column("user_id")]
+ public Guid? UserId { get; set; }
+}
diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.AuthorizeAccess/Infrastructure/Security/FormFlowJourneySignInHandler.cs b/TeachingRecordSystem/src/TeachingRecordSystem.AuthorizeAccess/Infrastructure/Security/FormFlowJourneySignInHandler.cs
index 36b83d58c..0ccb2cdce 100644
--- a/TeachingRecordSystem/src/TeachingRecordSystem.AuthorizeAccess/Infrastructure/Security/FormFlowJourneySignInHandler.cs
+++ b/TeachingRecordSystem/src/TeachingRecordSystem.AuthorizeAccess/Infrastructure/Security/FormFlowJourneySignInHandler.cs
@@ -64,7 +64,7 @@ public async Task SignInAsync(ClaimsPrincipal user, AuthenticationProperties? pr
var ticket = new AuthenticationTicket(user, properties, _scheme.Name);
- var result = await helper.OnSignedInWithOneLogin(journeyInstance, ticket);
+ var result = await helper.OnOneLoginCallback(journeyInstance, ticket);
// Override the redirect done by RemoteAuthenticationHandler
_context.Response.OnStarting(() => result.ExecuteAsync(_context));
diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.AuthorizeAccess/Infrastructure/Security/MatchToTeachingRecordAuthenticationHandler.cs b/TeachingRecordSystem/src/TeachingRecordSystem.AuthorizeAccess/Infrastructure/Security/MatchToTeachingRecordAuthenticationHandler.cs
index e6c85e659..2abd27197 100644
--- a/TeachingRecordSystem/src/TeachingRecordSystem.AuthorizeAccess/Infrastructure/Security/MatchToTeachingRecordAuthenticationHandler.cs
+++ b/TeachingRecordSystem/src/TeachingRecordSystem.AuthorizeAccess/Infrastructure/Security/MatchToTeachingRecordAuthenticationHandler.cs
@@ -35,23 +35,28 @@ public async Task ChallengeAsync(AuthenticationProperties? properties)
EnsureInitialized();
if (properties is null ||
- !properties.Items.TryGetValue(AuthenticationPropertiesItemKeys.OneLoginAuthenticationScheme, out var oneLoginAuthenticationScheme) ||
- oneLoginAuthenticationScheme is null ||
- !properties.Items.TryGetValue(AuthenticationPropertiesItemKeys.ServiceName, out var serviceName) ||
- serviceName is null ||
- !properties.Items.TryGetValue(AuthenticationPropertiesItemKeys.ServiceUrl, out var serviceUrl) ||
- serviceUrl is null)
+ !TryGetNonNullItem(AuthenticationPropertiesItemKeys.OneLoginAuthenticationScheme, out var oneLoginAuthenticationScheme) ||
+ !TryGetNonNullItem(AuthenticationPropertiesItemKeys.ServiceName, out var serviceName) ||
+ !TryGetNonNullItem(AuthenticationPropertiesItemKeys.ServiceUrl, out var serviceUrl))
{
throw new InvalidOperationException($"{nameof(AuthenticationProperties)} is missing one or more items.");
}
+ properties.Items.TryGetValue(AuthenticationPropertiesItemKeys.TrnToken, out var trnToken);
+
var journeyInstance = await helper.UserInstanceStateProvider.GetOrCreateSignInJourneyInstanceAsync(
_context,
- createState: () => new SignInJourneyState(properties.RedirectUri ?? "/", serviceName, serviceUrl, oneLoginAuthenticationScheme),
+ createState: () => new SignInJourneyState(properties.RedirectUri ?? "/", serviceName, serviceUrl, oneLoginAuthenticationScheme, trnToken),
updateState: state => state.Reset());
var result = helper.SignInWithOneLogin(journeyInstance);
await result.ExecuteAsync(_context);
+
+ bool TryGetNonNullItem(string key, [NotNullWhen(true)] out string? value)
+ {
+ value = default;
+ return properties?.Items.TryGetValue(key, out value) == true && value is not null;
+ }
}
public Task ForbidAsync(AuthenticationProperties? properties)
@@ -80,5 +85,6 @@ public static class AuthenticationPropertiesItemKeys
public const string OneLoginAuthenticationScheme = "OneLoginAuthenticationScheme";
public const string ServiceName = "ServiceName";
public const string ServiceUrl = "ServiceUrl";
+ public const string TrnToken = "TrnToken";
}
}
diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.AuthorizeAccess/Infrastructure/Security/OneLoginAuthenticationSchemeProvider.cs b/TeachingRecordSystem/src/TeachingRecordSystem.AuthorizeAccess/Infrastructure/Security/OneLoginAuthenticationSchemeProvider.cs
index 77a28fa7f..e152d7d6e 100644
--- a/TeachingRecordSystem/src/TeachingRecordSystem.AuthorizeAccess/Infrastructure/Security/OneLoginAuthenticationSchemeProvider.cs
+++ b/TeachingRecordSystem/src/TeachingRecordSystem.AuthorizeAccess/Infrastructure/Security/OneLoginAuthenticationSchemeProvider.cs
@@ -187,7 +187,7 @@ void IConfigureNamedOptions.Configure(string? name, OneLoginOpt
var signInJourneyHelper = context.HttpContext.RequestServices.GetRequiredService();
var journeyInstance = (await signInJourneyHelper.UserInstanceStateProvider.GetSignInJourneyInstanceAsync(context.HttpContext, journeyInstanceId))!;
- var result = await signInJourneyHelper.OnUserVerificationWithOneLoginFailed(journeyInstance);
+ var result = await signInJourneyHelper.OnVerificationFailed(journeyInstance);
await result.ExecuteAsync(context.HttpContext);
}
};
diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.AuthorizeAccess/Pages/DebugIdentity.cshtml b/TeachingRecordSystem/src/TeachingRecordSystem.AuthorizeAccess/Pages/DebugIdentity.cshtml
index ed0f4dde7..3a833bff6 100644
--- a/TeachingRecordSystem/src/TeachingRecordSystem.AuthorizeAccess/Pages/DebugIdentity.cshtml
+++ b/TeachingRecordSystem/src/TeachingRecordSystem.AuthorizeAccess/Pages/DebugIdentity.cshtml
@@ -1,7 +1,7 @@
@page "/debug"
@model TeachingRecordSystem.AuthorizeAccess.Pages.DebugIdentityModel
@{
- ViewBag.Title = "Identity information";
+ ViewBag.Title = "Debug One Login journey";
}