es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Establecer el atributo [Authorize] en la clase de hub de signalr solo funciona al conectarse al hub y no antes de cada método en el hub (ASP.NET Core 2.2).

Estoy intentando agregar autenticación a mi hub de SignalR, pero solo funciona para el método ‘negotiate’ y no para todas las solicitudes enviadas al hub.

En el archivo Startup.cs, dentro de ConfigureService, he agregado lo siguiente:

// Autenticación
services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
    options.TokenValidationParameters = GetTokenValidationParameters(authSettings.PublicKey);
    options.IncludeErrorDetails = true;
    options.Events = new JwtBearerEvents
    {
        OnMessageReceived = context =>
        {
            var accessToken = context.Request.Query["access_token"];
            var path = context.HttpContext.Request.Path;

            if (!string.IsNullOrEmpty(accessToken) &&
                (path.StartsWithSegments("/hubs")))
            {
                context.Token = accessToken;
            }
            return Task.CompletedTask;
        },
    };
});

En el método Configure he agregado lo siguiente:

app.UseWhen(ctx => ctx.Request.Path.StartsWithSegments("/hubs"), config => config.UseAuthentication());

Y he añadido el atributo [Authorize] en la clase del hub:

[Authorize]
public class ProtocolMethodsHub : Hub<iprotocolmethodshub>, IProtocolMethodsHub {}

He configurado un punto de interrupción en OnMessageReceived, pero solo se llama cuando me conecto a SignalR y no para cada solicitud que se envía a través del websocket.

¿Hay alguna manera de autenticar/autorizar cada solicitud al hub?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para autenticar/autorizar cada solicitud enviada al concentrador de SignalR, puede utilizar el método OnConnectedAsync en su clase Hub.

    Primero, elimine el atributo [Authorize] de la clase Hub. Luego, anule el método OnConnectedAsync en su clase Hub:

    public override async Task OnConnectedAsync()
    {
        var token = Context.GetHttpContext().Request.Query["access_token"];
        if (string.IsNullOrEmpty(token))
        {
            await Clients.Caller.SendAsync("ReceiveMessage", "Error de autenticación: falta el token de acceso.");
            Context.Abort();
            return;
        }
    
        var handler = new JwtSecurityTokenHandler();
        var validationParameters = GetTokenValidationParameters(authSettings.PublicKey);
        try
        {
            var user = handler.ValidateToken(token, validationParameters, out _);
            Context.User = user;
        }
        catch (Exception)
        {
            await Clients.Caller.SendAsync("ReceiveMessage", "Error de autenticación: token no válido.");
            Context.Abort();
            return;
        }
    
        await base.OnConnectedAsync();
    }
    

    En este método, puede acceder al access_token de la solicitud y validarlo utilizando el método GetTokenValidationParameters. Si el token no es válido, puede enviar un mensaje de error al cliente y abortar la conexión. Si el token es válido, puede establecer la propiedad User en el objeto Context.

    Con esta implementación, cada solicitud enviada al concentrador de SignalR desencadenará el método OnConnectedAsync y autenticará/autorizará la solicitud.

Comments are closed.