Skip to content

Commit

Permalink
Updated list of possible values for grant type
Browse files Browse the repository at this point in the history
  • Loading branch information
kirill-abblix committed Oct 8, 2024
1 parent 6e9ea27 commit 6e0026e
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 44 deletions.
4 changes: 3 additions & 1 deletion Abblix.Oidc.Server.Mvc/Model/ClientRegistrationRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
using Abblix.Jwt;
using Abblix.Oidc.Server.Common;
using Abblix.Oidc.Server.Common.Constants;
using Abblix.Oidc.Server.DeclarativeValidation;
using Abblix.Oidc.Server.Mvc.Binders;
Expand Down Expand Up @@ -69,7 +70,8 @@ public record ClientRegistrationRequest
[AllowedValues(
Common.Constants.GrantTypes.AuthorizationCode,
Common.Constants.GrantTypes.Implicit,
Common.Constants.GrantTypes.RefreshToken)]
Common.Constants.GrantTypes.RefreshToken,
Common.Constants.GrantTypes.Ciba)]
public string[] GrantTypes { get; init; } = { Common.Constants.GrantTypes.AuthorizationCode };

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,8 @@
using Abblix.Oidc.Server.Common;
using Abblix.Oidc.Server.Common.Constants;
using Abblix.Oidc.Server.Endpoints.Authorization.Interfaces;

using Microsoft.Extensions.Logging;



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

/// <summary>
Expand All @@ -38,8 +35,10 @@ namespace Abblix.Oidc.Server.Endpoints.Authorization.Validation;
/// </summary>
public class FlowTypeValidator : SyncAuthorizationContextValidatorBase
{
private readonly ILogger _logger;

/// <summary>
/// Initializes a new instance of the <see cref="FlowTypeValidator"/> class with a logger.
/// Initializes a new instance of the <see cref="FlowTypeValidator" /> class with a logger.
/// The logger is used for recording the validation activities, aiding in troubleshooting and auditing.
/// </summary>
/// <param name="logger">The logger to be used for logging purposes.</param>
Expand All @@ -48,15 +47,13 @@ public FlowTypeValidator(ILogger<FlowTypeValidator> logger)
_logger = logger;
}

private readonly ILogger _logger;

/// <summary>
/// Validates the flow type specified in the authorization request.
/// This method checks if the flow type is supported and aligns with the OAuth 2.0 specifications.
/// </summary>
/// <param name="context">The validation context containing client and request information.</param>
/// <returns>
/// An <see cref="AuthorizationRequestValidationError"/> if the flow type is not valid or supported,
/// An <see cref="AuthorizationRequestValidationError" /> if the flow type is not valid or supported,
/// or null if the flow type is valid.
/// </returns>
protected override AuthorizationRequestValidationError? Validate(AuthorizationValidationContext context)
Expand All @@ -65,14 +62,15 @@ public FlowTypeValidator(ILogger<FlowTypeValidator> logger)

if (!ResponseTypeAllowed(context))
{
_logger.LogWarning("The response type {@ResponseType} is not allowed for the client", new object?[] { responseType });
return UnsupportedResponseType("The response type is not allowed for the client");
_logger.LogWarning("The response type {@ResponseType} is not allowed for the client",
new object?[] { responseType });
return UnsupportedResponseType("The response type is not allowed for the client");
}

if (!TryDetectFlowType(responseType, out var flowType, out var responseMode))
{
_logger.LogWarning("The response type {@ResponseType} is not valid", new object?[] { responseType });
return UnsupportedResponseType("The response type is not supported");
_logger.LogWarning("The response type {@ResponseType} is not valid", new object?[] { responseType });
return UnsupportedResponseType("The response type is not supported");
}

context.FlowType = flowType;
Expand All @@ -81,11 +79,11 @@ public FlowTypeValidator(ILogger<FlowTypeValidator> logger)

AuthorizationRequestValidationError UnsupportedResponseType(string message)
{
context.ResponseMode = context.Request.ResponseMode ?? ResponseModes.Query;
context.ResponseMode = context.Request.ResponseMode ?? ResponseModes.Query;

return context.Error(
ErrorCodes.UnsupportedResponseType,
message);
return context.Error(
ErrorCodes.UnsupportedResponseType,
message);
}
}

Expand All @@ -99,20 +97,20 @@ AuthorizationRequestValidationError UnsupportedResponseType(string message)
/// </returns>
private static bool ResponseTypeAllowed(AuthorizationValidationContext context)
{
var responseType = context.Request.ResponseType;
var responseType = context.Request.ResponseType;

// If the response type is not specified, it means the request is invalid
if (responseType == null)
return false;
// If the response type is not specified, it means the request is invalid
if (responseType == null)
return false;

// Convert the requested response type array into a hashset for faster lookup
var responseTypeSet = responseType.ToHashSet(StringComparer.Ordinal);
// Convert the requested response type array into a hashset for faster lookup
var responseTypeSet = responseType.ToHashSet(StringComparer.Ordinal);

// Check if any of the allowed response types matches the requested response type
return Array.Exists(
context.ClientInfo.AllowedResponseTypes,
allowedResponseType => responseTypeSet.Count == allowedResponseType.Length &&
Array.TrueForAll(allowedResponseType, responseTypeSet.Contains));
// Check if any of the allowed response types matches the requested response type
return Array.Exists(
context.ClientInfo.AllowedResponseTypes,
allowedResponseType => responseTypeSet.Count == allowedResponseType.Length &&
Array.TrueForAll(allowedResponseType, responseTypeSet.Contains));
}

/// <summary>
Expand All @@ -122,19 +120,20 @@ private static bool ResponseTypeAllowed(AuthorizationValidationContext context)
/// <param name="flowType">The detected flow type, if successful.</param>
/// <param name="responseMode">The default response mode for the detected flow type, if successful.</param>
/// <returns>A boolean value indicating whether the detection was successful.</returns>
private static bool TryDetectFlowType([NotNullWhen(true)] string[]? responseType, out FlowTypes flowType, out string responseMode)
{
var code = responseType.HasFlag(ResponseTypes.Code);
var token = responseType.HasFlag(ResponseTypes.Token) || responseType.HasFlag(ResponseTypes.IdToken);

(var result, flowType, responseMode) = (code, token) switch
{
(code: true, token: false) => (true, FlowTypes.AuthorizationCode, ResponseModes.Query),
(code: false, token: true) => (true, FlowTypes.Implicit, ResponseModes.Fragment),
(code: true, token: true) => (true, FlowTypes.Hybrid, ResponseModes.Fragment),
_ => (false, default, default!),
};

return result;
}
private static bool TryDetectFlowType([NotNullWhen(true)] string[]? responseType, out FlowTypes flowType,
out string responseMode)
{
var code = responseType.HasFlag(ResponseTypes.Code);
var token = responseType.HasFlag(ResponseTypes.Token) || responseType.HasFlag(ResponseTypes.IdToken);

(var result, flowType, responseMode) = (code, token) switch
{
(code: true, token: false) => (true, FlowTypes.AuthorizationCode, ResponseModes.Query),
(code: false, token: true) => (true, FlowTypes.Implicit, ResponseModes.Fragment),
(code: true, token: true) => (true, FlowTypes.Hybrid, ResponseModes.Fragment),
_ => (false, default, default!)
};

return result;
}
}
5 changes: 3 additions & 2 deletions Abblix.Oidc.Server/Model/ClientRegistrationRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ public record ClientRegistrationRequest
[AllowedValues(
Common.Constants.GrantTypes.AuthorizationCode,
Common.Constants.GrantTypes.Implicit,
Common.Constants.GrantTypes.RefreshToken)]
Common.Constants.GrantTypes.RefreshToken,
Common.Constants.GrantTypes.Ciba)]
public string[] GrantTypes { get; init; } = { Common.Constants.GrantTypes.AuthorizationCode };

/// <summary>
Expand All @@ -73,7 +74,7 @@ public record ClientRegistrationRequest
public string ApplicationType { get; init; } = ApplicationTypes.Web;

/// <summary>
/// Array of e-mail addresses of people responsible for this client.
/// E-mail addresses of people responsible for this client.
/// </summary>
[JsonPropertyName(Parameters.Contacts)]
public string[]? Contacts { get; init; }
Expand Down

0 comments on commit 6e0026e

Please sign in to comment.