Skip to content

Commit

Permalink
Replace scalar VectorOfTrust with collection VectorsOfTrust (#18)
Browse files Browse the repository at this point in the history
  • Loading branch information
gunndabad authored May 31, 2024
1 parent f2f186e commit cf42fe8
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 24 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

Adds support for JWT-secured OAuth 2.0 authorisation request (JAR) and enables it by default.

Replaces the `string` `VectorOfTrust` property on `OneLoginOptions` with an `ICollection<string>` property `VectorOfTrusts`.

## 0.3.1

Adds `NationalInsuranceNumber` member to `OneLoginClaimTypes`.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ builder.Services.AddAuthentication(defaultScheme: OneLoginDefaults.Authenticatio

// Configure vectors of trust.
// See the One Login docs for the various options to use here.
options.VectorOfTrust = @"[""Cl""]";
options.VectorsOfTrust = ["Cl"];

// Override the cookie name prefixes (optional)
options.CorrelationCookie.Name = "my-app-onelogin-correlation.";
Expand Down
45 changes: 31 additions & 14 deletions src/GovUk.OneLogin.AspNetCore/AuthenticationPropertiesExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Diagnostics.CodeAnalysis;
using System.Text.Json;
using Microsoft.AspNetCore.Authentication;

namespace GovUk.OneLogin.AspNetCore;
Expand All @@ -8,48 +8,65 @@ namespace GovUk.OneLogin.AspNetCore;
/// </summary>
public static class AuthenticationPropertiesExtensions
{
private const string VectorOfTrustKey = "GovUk.OneLogin.AspNetCore.VectorOfTrust";
private const string VectorsOfTrustKey = "GovUk.OneLogin.AspNetCore.VectorsOfTrust";

/// <summary>
/// Gets the vector of trust to use when authenticating using GOV.UK One Login.
/// Gets the vectors of trust to use when authenticating using GOV.UK One Login.
/// </summary>
/// <param name="authenticationProperties">The <see cref="AuthenticationProperties"/>.</param>
/// <returns>The vector of trust.</returns>
/// <exception cref="InvalidOperationException"> if the vector of trust has not been set.</exception>
public static string GetVectorOfTrust(this AuthenticationProperties authenticationProperties)
public static IReadOnlyCollection<string> GetVectorsOfTrust(this AuthenticationProperties authenticationProperties)
{
ArgumentNullException.ThrowIfNull(authenticationProperties);

if (!TryGetVectorOfTrust(authenticationProperties, out var value))
if (!TryGetVectorsOfTrust(authenticationProperties, out var value))
{
throw new InvalidOperationException("Vector of trust has not been set.");
throw new InvalidOperationException("Vectors of trust have not been set.");
}

return value;
}

/// <summary>
/// Sets the vector of trust to use when authenticating using GOV.UK One Login.
/// Sets the vectors of trust to use when authenticating using GOV.UK One Login.
/// </summary>
/// <param name="authenticationProperties">The <see cref="AuthenticationProperties"/>.</param>
/// <param name="value">The vector of trust.</param>
public static void SetVectorOfTrust(this AuthenticationProperties authenticationProperties, string? value)
/// <param name="value">The vectors of trust.</param>
public static void SetVectorsOfTrust(this AuthenticationProperties authenticationProperties, IEnumerable<string>? value)
{
ArgumentNullException.ThrowIfNull(authenticationProperties);

authenticationProperties.SetString(VectorOfTrustKey, value);
if (value is null)
{
authenticationProperties.Items.Remove(VectorsOfTrustKey);
}
else
{
var stringValue = JsonSerializer.Serialize<string[]>(value.ToArray());
authenticationProperties.SetString(VectorsOfTrustKey, stringValue);
}
}

/// <summary>
/// Gets the vector of trust to use when authenticating using GOV.UK One Login.
/// Gets the vectors of trust to use when authenticating using GOV.UK One Login.
/// </summary>
/// <param name="authenticationProperties">The <see cref="AuthenticationProperties"/>.</param>
/// <param name="value">The vector of trust.</param>
/// <param name="value">The vectors of trust.</param>
/// <returns><see langword="true"/> if the value was successfully retrieved.</returns>
public static bool TryGetVectorOfTrust(this AuthenticationProperties authenticationProperties, [NotNullWhen(true)] out string? value)
public static bool TryGetVectorsOfTrust(this AuthenticationProperties authenticationProperties, out IReadOnlyCollection<string> value)
{
ArgumentNullException.ThrowIfNull(authenticationProperties);

return authenticationProperties.Items.TryGetValue(VectorOfTrustKey, out value);
if (authenticationProperties.Items.TryGetValue(VectorsOfTrustKey, out var stringValue) && stringValue is not null)
{
value = JsonSerializer.Deserialize<string[]>(stringValue)!;
return true;
}
else
{
value = Array.Empty<string>();
return false;
}
}
}
28 changes: 19 additions & 9 deletions src/GovUk.OneLogin.AspNetCore/OneLoginOptions.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Text.Json;
using System.Text.Json.Nodes;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
Expand All @@ -16,6 +17,7 @@ namespace GovUk.OneLogin.AspNetCore;
public class OneLoginOptions
{
private string? _claimsRequest;
private ICollection<string> _vectorsOfTrust;

/// <summary>
/// Initializes a new <see cref="OneLoginOptions"/>.
Expand Down Expand Up @@ -46,9 +48,9 @@ public OneLoginOptions()
OpenIdConnectOptions.Events = Events = new DelegateEventsWrapper(this);

ClientAssertionJwtExpiry = TimeSpan.FromMinutes(5); // One Login docs recommend 5 minutes
VectorOfTrust = @"[""Cl.Cm""]";
_vectorsOfTrust = new List<string>() { "Cl.Cm" };

Claims = new HashSet<string>();
Claims = new List<string>();

Scope.Clear();
Scope.Add("openid");
Expand Down Expand Up @@ -99,10 +101,17 @@ public string? ClientId
public string? UiLocales { get; set; }

/// <summary>
/// Gets or sets the 'vtr'.
/// Gets or sets the vectors of trust.
/// </summary>
[DisallowNull]
public string? VectorOfTrust { get; set; }
public ICollection<string> VectorsOfTrust
{
get => _vectorsOfTrust;
set
{
ArgumentNullException.ThrowIfNull(value);
_vectorsOfTrust = value;
}
}

/// <summary>
/// Gets the list of claims to request.
Expand Down Expand Up @@ -209,12 +218,13 @@ internal Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedContext conte

internal async Task OnRedirectToIdentityProvider(RedirectContext context)
{
var vectorOfTrust = (context.Properties.TryGetVectorOfTrust(out var value) ? value : VectorOfTrust) ??
var vectorsOfTrust = (context.Properties.TryGetVectorsOfTrust(out var value) ? (IEnumerable<string>)value : VectorsOfTrust) ??
throw new InvalidOperationException(
$"VectorOfTrust has not been set. " +
$"Either specify it on {nameof(OneLoginOptions)} or by calling {nameof(AuthenticationPropertiesExtensions.SetVectorOfTrust)} on {nameof(AuthenticationOptions)}.");
$"VectorsOfTrust has not been set. " +
$"Either specify it on {nameof(OneLoginOptions)} or by calling {nameof(AuthenticationPropertiesExtensions.SetVectorsOfTrust)} on {nameof(AuthenticationProperties)}.");

context.ProtocolMessage.Parameters.Add("vtr", vectorOfTrust);
var vtr = JsonSerializer.Serialize(vectorsOfTrust);
context.ProtocolMessage.Parameters.Add("vtr", vtr);

if (Claims.Count > 0)
{
Expand Down

0 comments on commit cf42fe8

Please sign in to comment.