Home > database >  Error: Failed to complete negotiation with the server: Error : Status code '401'
Error: Failed to complete negotiation with the server: Error : Status code '401'

Time:01-15

I'm using SignalR and angular to create a chat between clients, after the client logged in successfully with jwt token. Once I've added -

[Authorize]

to my hub, I'm getting this error while trying to connect to SignalR -

Debug: HubConnection failed to start successfully because of error 'Error: Failed to complete negotiation with the server: Error: : Status code '401''.

Before I added this attribute, my app connected successfully to SignalR so I know the problem is authorization. What am I doing wrong?

UserHub-

[Authorize]
public class UserHub : Hub

Program.cs-

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddCors(options =>
{
    options.AddPolicy("CorsPolicy", builder => builder
        .WithOrigins("http://localhost:4200")
        .AllowAnyMethod()
        .AllowAnyHeader()
        .AllowCredentials()
        .SetIsOriginAllowed((host) => true));
});

builder.Services.AddDbContext<TalkBackDbContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("TalkBackConnectionString")));

builder.Services.AddScoped<IContactRepository, ContactsRepository>();
builder.Services.AddScoped<IWebAPIService, WebAPIService>();
builder.Services.AddScoped<ISignalrService, SignalrService>();
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddSignalR(); 
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
{
    options.TokenValidationParameters = new TokenValidationParameters()
    {
        ValidateIssuer = false,
        ValidateAudience = false,
        ValidAudience = builder.Configuration["Jwt:Audience"],
        ValidIssuer = builder.Configuration["Jwt:Issuer"],
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]))
    };
    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("/user")))
            {
                context.Token = accessToken;
            }
            return Task.CompletedTask;
        }
    };
});

Client-

public startSignalrConnection(connectionUrl: any) {
return new Promise<any>((resolve, reject) => {
  this.hubConnection = new HubConnectionBuilder()
    .withUrl(connectionUrl, { 
      withCredentials: false,
    accessTokenFactory: () => localStorage.getItem('jwt')!,
   })
    .configureLogging(LogLevel.Debug)
    .build();

CodePudding user response:

After many tries, I found out what was the problem. I missed this line on Program.cs -

app.UseAuthentication();

I've also edited my token (on another microservice) to be the same like here, and added this line -

ValidateIssuerSigningKey=true

Now I can access to SignalR.

  • Related