Skip to content

Refactor IWebSocketAuthenticationService #1177

@Shane32

Description

@Shane32

Suggest changing method AuthenticateAsync to have an AuthenticationRequest class that includes AuthenticationSchemes, as follows:

/// <summary>
/// Authenticates an incoming GraphQL over WebSockets request with the
/// connection initialization message.  A typical implementation will
/// set the <see cref="HttpContext.User"/> property after reading the
/// authorization token.  This service must be registered as a singleton
/// in the dependency injection framework.
/// </summary>
public interface IWebSocketAuthenticationService
{
    /// <summary>
    /// Authenticates an incoming GraphQL over WebSockets request with the connection initialization message.  The implementation should
    /// set the <paramref name="authenticationRequest"/>.<see cref="AuthenticationRequest.Connection">Connection</see>.<see cref="IWebSocketConnection.HttpContext">HttpContext</see>.<see cref="HttpContext.User">User</see>
    /// property after validating the provided credentials.
    /// <br/><br/>
    /// After calling this method to authenticate the request, the infrastructure will authorize the incoming request via the
    /// <see cref="GraphQLHttpMiddlewareOptions.AuthorizationRequired"/>, <see cref="GraphQLHttpMiddlewareOptions.AuthorizedRoles"/> and
    /// <see cref="GraphQLHttpMiddlewareOptions.AuthorizedPolicy"/> properties.
    /// </summary>
    Task AuthenticateAsync(AuthenticationRequest authenticationRequest);
}

/// <summary>
/// Represents an authentication request within the GraphQL ASP.NET Core WebSocket context.
/// </summary>
public class AuthenticationRequest
{
    /// <summary>
    /// Gets the WebSocket connection associated with the authentication request.
    /// </summary>
    /// <value>
    /// An instance of <see cref="IWebSocketConnection"/> representing the active WebSocket connection.
    /// </value>
    public IWebSocketConnection Connection { get; }

    /// <summary>
    /// Gets the subprotocol used for the WebSocket communication.
    /// </summary>
    /// <value>
    /// A <see cref="string"/> specifying the subprotocol negotiated for the WebSocket connection.
    /// </value>
    public string SubProtocol { get; }

    /// <summary>
    /// Gets the operation message containing details of the authentication operation.
    /// </summary>
    /// <value>
    /// An instance of <see cref="OperationMessage"/> that encapsulates the specifics of the authentication request.
    /// </value>
    public OperationMessage OperationMessage { get; }

    /// <summary>
    /// Gets a list of the authentication schemes the authentication requirements are evaluated against.
    /// When no schemes are specified, the default authentication scheme is used.
    /// </summary>
    public IEnumerable<string> AuthenticationSchemes { get; }

    /// <summary>
    /// Initializes a new instance of the <see cref="AuthenticationRequest"/> class.
    /// </summary>
    public AuthenticationRequest(IWebSocketConnection connection, string subProtocol, OperationMessage operationMessage, IEnumerable<string> authenticationSchemes)
    {
        Connection = connection;
        SubProtocol = subProtocol;
        OperationMessage = operationMessage;
        AuthenticationSchemes = authenticationSchemes;
    }
}

This allows for the authentication handler to attempt each scheme specified by the middleware options.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions