Skip to content

Commit

Permalink
Merge branch 'master' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
kirill-abblix committed Dec 1, 2024
2 parents 22234af + e9f1621 commit 7ac2b6f
Show file tree
Hide file tree
Showing 15 changed files with 130 additions and 46 deletions.
10 changes: 5 additions & 5 deletions Abblix.DependencyInjection/Abblix.DependencyInjection.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,17 @@
<PackageReleaseNotes>For detailed release notes, visit: https://github.com/Abblix/Oidc.Server/releases</PackageReleaseNotes>
<PackageIcon>Abblix.png</PackageIcon>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
<AssemblyVersion>1.3.0.1</AssemblyVersion>
<FileVersion>1.3.0.1</FileVersion>
<PackageVersion>1.3.0.1</PackageVersion>
<AssemblyVersion>1.3.1.0</AssemblyVersion>
<FileVersion>1.3.1.0</FileVersion>
<PackageVersion>1.3.1.0</PackageVersion>
</PropertyGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="9.*" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.0" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net6.0' OR '$(TargetFramework)' == 'net7.0' OR '$(TargetFramework)' == 'net8.0'">
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.*" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.0" />
</ItemGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion Abblix.Jwt.UnitTests/Abblix.Jwt.UnitTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="xunit" Version="2.9.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
12 changes: 6 additions & 6 deletions Abblix.Jwt/Abblix.Jwt.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,21 @@
<PackageReleaseNotes>For detailed release notes, visit: https://github.com/Abblix/Oidc.Server/releases</PackageReleaseNotes>
<PackageIcon>Abblix.png</PackageIcon>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
<AssemblyVersion>1.3.0.1</AssemblyVersion>
<FileVersion>1.3.0.1</FileVersion>
<PackageVersion>1.3.0.1</PackageVersion>
<AssemblyVersion>1.3.1.0</AssemblyVersion>
<FileVersion>1.3.1.0</FileVersion>
<PackageVersion>1.3.1.0</PackageVersion>
</PropertyGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="9.*" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.0" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net6.0' OR '$(TargetFramework)' == 'net7.0' OR '$(TargetFramework)' == 'net8.0'">
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.*" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.0" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.2.0" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.2.1" />
<PackageReference Include="System.Linq.Async" Version="6.0.1" />
</ItemGroup>

Expand Down
6 changes: 3 additions & 3 deletions Abblix.Oidc.Server.Mvc/Abblix.Oidc.Server.Mvc.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@
<PackageReleaseNotes>For detailed release notes, visit: https://github.com/Abblix/Oidc.Server/releases</PackageReleaseNotes>
<PackageIcon>Abblix.png</PackageIcon>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
<AssemblyVersion>1.3.0.1</AssemblyVersion>
<FileVersion>1.3.0.1</FileVersion>
<PackageVersion>1.3.0.1</PackageVersion>
<AssemblyVersion>1.3.1.0</AssemblyVersion>
<FileVersion>1.3.1.0</FileVersion>
<PackageVersion>1.3.1.0</PackageVersion>
</PropertyGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion Abblix.Oidc.Server.Tests/Abblix.Oidc.Server.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="xunit" Version="2.9.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<ItemGroup>
<PackageReference Include="Moq" Version="4.20.72" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="xunit" Version="2.9.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
22 changes: 11 additions & 11 deletions Abblix.Oidc.Server/Abblix.Oidc.Server.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
<PackageReleaseNotes>For detailed release notes, visit: https://github.com/Abblix/Oidc.Server/releases</PackageReleaseNotes>
<PackageIcon>Abblix.png</PackageIcon>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
<AssemblyVersion>1.3.0.1</AssemblyVersion>
<FileVersion>1.3.0.1</FileVersion>
<PackageVersion>1.3.0.1</PackageVersion>
<AssemblyVersion>1.3.1.0</AssemblyVersion>
<FileVersion>1.3.1.0</FileVersion>
<PackageVersion>1.3.1.0</PackageVersion>
</PropertyGroup>

<ItemGroup>
Expand All @@ -33,17 +33,17 @@
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="9.*" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="9.*" />
<PackageReference Include="Microsoft.Extensions.Http" Version="9.*" />
<PackageReference Include="Microsoft.Extensions.Options" Version="9.*" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Options" Version="9.0.0" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net6.0' OR '$(TargetFramework)' == 'net7.0' OR '$(TargetFramework)' == 'net8.0'">
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.*" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.*" />
<PackageReference Include="Microsoft.Extensions.Http" Version="8.*" />
<PackageReference Include="Microsoft.Extensions.Options" Version="8.*" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Options" Version="9.0.0" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,23 @@
// CONTACT: For license inquiries or permissions, contact Abblix LLP at
// info@abblix.com

using Abblix.Oidc.Server.Common.Constants;
using Abblix.Oidc.Server.Endpoints.Authorization.Validation;
using Abblix.Oidc.Server.Features.ClientInformation;
using Abblix.Oidc.Server.Features.Licensing;
using Abblix.Oidc.Server.Features.UriValidation;
using Abblix.Oidc.Server.Model;
using Abblix.Utils;
using Microsoft.Extensions.Logging;
using static Abblix.Oidc.Server.Model.AuthorizationRequest;

namespace Abblix.Oidc.Server.Endpoints.Authorization.RequestFetching;

/// <summary>
/// Handles fetching of authorization request objects from a specified request URI.
/// This class is responsible for retrieving the pre-registered request objects from an external location
/// This class is responsible for retrieving pre-registered request objects from an external location
/// indicated by a URI, ensuring the request is complete and valid.
/// It helps enable dynamic request objects, allowing authorization servers to fetch additional
/// It enables dynamic request objects, allowing authorization servers to fetch additional
/// data required for processing the authorization request.
/// </summary>
public class RequestUriFetcher : IAuthorizationRequestFetcher
Expand All @@ -41,21 +46,24 @@ public class RequestUriFetcher : IAuthorizationRequestFetcher
/// This constructor sets up the necessary services for fetching the request objects over HTTP.
/// </summary>
/// <param name="logger">The logger used for logging warnings when request fetching fails.</param>
/// <param name="clientInfoProvider">Service to retrieve client-specific information for validation.</param>
/// <param name="httpClientFactory">
/// The factory used to create <see cref="HttpClient"/> instances for making HTTP requests to the specified URI.
/// </param>
public RequestUriFetcher(
ILogger<RequestUriFetcher> logger,
IClientInfoProvider clientInfoProvider,
IHttpClientFactory httpClientFactory)
{
_logger = logger;
_clientInfoProvider = clientInfoProvider;
_httpClientFactory = httpClientFactory;
}

private readonly ILogger _logger;
private readonly IClientInfoProvider _clientInfoProvider;
private readonly IHttpClientFactory _httpClientFactory;


/// <summary>
/// Asynchronously fetches the authorization request object from the given request URI.
/// This method retrieves the request object if the request URI is valid and contains an absolute URL.
Expand All @@ -74,17 +82,44 @@ public async Task<FetchResult> FetchAsync(AuthorizationRequest request)
{
if (request is { Request: not null, RequestUri: not null })
{
// Log an error if both request parameters are provided, as this violates the request format rules.
return ErrorFactory.InvalidRequest(
$"Only one of the parameters {Parameters.Request} and {Parameters.RequestUri} can be used");
}

if (request is not { RequestUri: { IsAbsoluteUri: true } requestUri })
{
return request;
return request; // Pass through if no valid RequestUri is provided
}

if (requestUri.Scheme != Uri.UriSchemeHttps)
{
return ErrorFactory.ValidationError(
ErrorCodes.InvalidRequestUri, "The request URI must be an https URI");
}

var clientId = request.ClientId;
if (clientId is null)
{
return ErrorFactory.ValidationError(
ErrorCodes.UnauthorizedClient, "The client id is required");
}

var clientInfo = await _clientInfoProvider.TryFindClientAsync(clientId).WithLicenseCheck();
if (clientInfo == null)
{
_logger.LogWarning("The client with id {ClientId} was not found", new Sanitized(clientId));
return ErrorFactory.ValidationError(
ErrorCodes.UnauthorizedClient, "The client is not authorized");
}

var requestUriValidator = UriValidatorFactory.Create(true, clientInfo.RequestUris);
if (!requestUriValidator.IsValid(requestUri))
{
return ErrorFactory.ValidationError(
ErrorCodes.InvalidRequestUri, "The request URI is not allowed for the client");
}

// If the request contains a valid absolute URI, proceed to fetch the request object.
// If the request contains a valid absolute URI, proceed to fetch the request object
var client = _httpClientFactory.CreateClient();
string requestObject;
try
Expand All @@ -98,7 +133,7 @@ public async Task<FetchResult> FetchAsync(AuthorizationRequest request)
$"Unable to get the request object from {Parameters.RequestUri}");
}

// Return the updated request with the fetched request object and nullify the redirect URI.
// Return the updated request with the fetched request object and nullify the redirect URI
return request with { RedirectUri = null, Request = requestObject };
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,12 @@ public ClientValidator(
public async Task<AuthorizationRequestValidationError?> ValidateAsync(AuthorizationValidationContext context)
{
var clientId = context.Request.ClientId;
var clientInfo = await _clientInfoProvider.TryFindClientAsync(clientId.NotNull(nameof(clientId))).WithLicenseCheck();
if (clientId is null)
{
return context.Error(ErrorCodes.UnauthorizedClient, "The client id is required");
}

var clientInfo = await _clientInfoProvider.TryFindClientAsync(clientId).WithLicenseCheck();
if (clientInfo == null)
{
_logger.LogWarning("The client with id {ClientId} was not found", new Sanitized(clientId));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

using Abblix.Oidc.Server.Common.Constants;
using Abblix.Oidc.Server.Endpoints.Authorization.Interfaces;
using Abblix.Oidc.Server.Endpoints.Authorization.RequestFetching;

namespace Abblix.Oidc.Server.Endpoints.Authorization.Validation;

Expand Down
13 changes: 12 additions & 1 deletion Abblix.Oidc.Server/Features/ClientInformation/ClientInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public record ClientInfo(string ClientId)
/// <summary>
/// Classifies the client based on its ability to securely maintain a client secret.
/// This classification influences the authorization flow and token endpoint authentication method that
/// the client can utilize. Public clients, such as mobile or desktop applications, can’t securely store secrets,
/// the client can use. Public clients, such as mobile or desktop applications, can’t securely store secrets,
/// while confidential clients, like server-side web applications, can.
/// </summary>
public ClientType ClientType { get; set; } = ClientType.Public;
Expand Down Expand Up @@ -236,4 +236,15 @@ public record ClientInfo(string ClientId)
/// Indicates whether the backchannel authentication process supports user codes for this client.
/// </summary>
public bool BackChannelUserCodeParameter { get; set; } = false;

/// <summary>
/// The list of allowed URI values to validate the <c>request_uri</c> parameter in authorization requests.
/// </summary>
/// <remarks>
/// The <c>request_uri</c> parameter references a hosted authorization request object.
/// This property defines the valid URIs
/// that can be used in the <c>request_uri</c> parameter for authorization requests,
/// ensuring that only authorized and pre-approved URIs are accepted by the server.
/// </remarks>
public Uri[] RequestUris { get; set; } = Array.Empty<Uri>();
}
41 changes: 36 additions & 5 deletions Abblix.Oidc.Server/Features/UriValidation/UriValidatorFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,24 +24,55 @@ namespace Abblix.Oidc.Server.Features.UriValidation;

/// <summary>
/// Provides a factory method for creating URI validators. Depending on the number of URIs provided,
/// it creates either a single exact match validator or a composite validator that combines multiple exact match validators.
/// it creates either a single exact match validator or a composite validator that combines multiple exact
/// match validators.
/// </summary>
public static class UriValidatorFactory
{
/// <summary>
/// Creates a URI validator based on the given URIs.
/// If only one URI is provided, it returns an <see cref="ExactMatchUriValidator"/> for that URI.
/// If multiple URIs are provided, it returns a <see cref="CompositeUriValidator"/> that validates against all given URIs.
/// If multiple URIs are provided, it returns a <see cref="CompositeUriValidator"/> that validates against
/// all given URIs.
/// </summary>
/// <param name="validUris">An array of URIs to be used for validation.</param>
/// <returns>
/// An <see cref="IUriValidator"/> instance that can validate URIs based on the provided URIs.
/// Returns an <see cref="ExactMatchUriValidator"/> for a single URI or a <see cref="CompositeUriValidator"/> for multiple URIs.
/// Returns an <see cref="ExactMatchUriValidator"/> for a single URI or a <see cref="CompositeUriValidator"/>
/// for multiple URIs.
/// </returns>
/// <remarks>
/// Use this method when you want to create a validator with default behavior for handling query strings
/// and fragments during validation.
/// </remarks>
public static IUriValidator Create(params Uri[] validUris)
=> Create(false, validUris);

/// <summary>
/// Creates a URI validator based on the given URIs,
/// with an option to ignore query strings and fragments during validation.
/// </summary>
/// <param name="ignoreQueryAndFragment">
/// Specifies whether query strings and fragments should be ignored during validation.</param>
/// <param name="validUris">An array of URIs to be used for validation.</param>
/// <returns>
/// An <see cref="IUriValidator"/> instance that can validate URIs based on the provided URIs.
/// Returns an <see cref="ExactMatchUriValidator"/> for a single URI or a <see cref="CompositeUriValidator"/>
/// for multiple URIs.
/// </returns>
/// <remarks>
/// - If only one URI is provided, an <see cref="ExactMatchUriValidator"/> is returned.
/// - If multiple URIs are provided, a <see cref="CompositeUriValidator"/> is returned, which validates
/// against all specified URIs.
/// - The `ignoreQueryAndFragment` parameter determines whether query strings and fragments in URIs
/// are considered during validation.
/// </remarks>
public static IUriValidator Create(bool ignoreQueryAndFragment, params Uri[] validUris)
=> validUris.Length switch
{
1 => new ExactMatchUriValidator(validUris[0]),
_ => new CompositeUriValidator(from validUri in validUris select new ExactMatchUriValidator(validUri)),
1 => new ExactMatchUriValidator(validUris[0], ignoreQueryAndFragment),
_ => new CompositeUriValidator(
from validUri in validUris
select new ExactMatchUriValidator(validUri, ignoreQueryAndFragment)),
};
}
1 change: 1 addition & 0 deletions Abblix.Oidc.sln
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
.gitattributes = .gitattributes
.gitignore = .gitignore
.github\workflows\ci-cd.yml = .github\workflows\ci-cd.yml
.github\workflows\codeql-analysis.yml = .github\workflows\codeql-analysis.yml
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Abblix.Utils.UnitTests", "Abblix.Utils.UnitTests\Abblix.Utils.UnitTests.csproj", "{B4F3431F-A71C-44F4-A2BF-DCB00D17739E}"
Expand Down
2 changes: 1 addition & 1 deletion Abblix.Utils.UnitTests/Abblix.Utils.UnitTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="xunit" Version="2.9.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
6 changes: 3 additions & 3 deletions Abblix.Utils/Abblix.Utils.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
<PackageReleaseNotes>For detailed release notes, visit: https://github.com/Abblix/Oidc.Server/releases</PackageReleaseNotes>
<PackageIcon>Abblix.png</PackageIcon>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
<AssemblyVersion>1.3.0.1</AssemblyVersion>
<FileVersion>1.3.0.1</FileVersion>
<PackageVersion>1.3.0.1</PackageVersion>
<AssemblyVersion>1.3.1.0</AssemblyVersion>
<FileVersion>1.3.1.0</FileVersion>
<PackageVersion>1.3.1.0</PackageVersion>
</PropertyGroup>

<ItemGroup>
Expand Down

0 comments on commit 7ac2b6f

Please sign in to comment.