首页 > 解决方案 > 授权在 ASP Core 中未连接的 signalR 集线器

问题描述

授权 signalR 集线器未使用前端角度连接到集线器,无法调用 jwt 访问令牌到集线器连接。如何将asp核心中的授权信号器集线器与角度项目连接我的项目中有以下代码,

这是我的代码

    public class Startup
    {
    readonly string CorsPolicy = "CorsPolicy";
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();
        services.AddCors(options =>
        {
            options.AddPolicy(name: CorsPolicy,
                builder =>
                {
                    builder
                        .AllowAnyHeader()
                        .AllowAnyMethod()

                     .WithOrigins("http://localhost:3000", "http://localhost:4200", "http://localhost:1234")
                        .AllowCredentials();
                });
        });

        services.AddControllers();

        services.AddSignalR()
        .AddJsonProtocol(options =>
        {
            options.PayloadSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
        });

       //jwt token
        services.AddAuthentication(opt =>
        {
            opt.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            opt.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            opt.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
        })
       .AddJwtBearer(options =>
       {
           options.RequireHttpsMetadata = false;
           options.SaveToken = false;
           options.TokenValidationParameters = new TokenValidationParameters
           {
               ValidateIssuer = false,
               ValidateAudience = false,
               ValidateLifetime = true,
               ValidateIssuerSigningKey = true,

               ValidIssuer = Configuration["Jwt:Issuer"],
               ValidAudience = Configuration["Jwt:Audience"],
               IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"])),
               ClockSkew = TimeSpan.Zero
           };

           options.Events = new JwtBearerEvents
           {
               OnMessageReceived = context =>
               {
                   var accessToken = "Bearer " + context.Request.Query["access_token"];

                  var path = context.HttpContext.Request.Path;
                   if (!string.IsNullOrEmpty(accessToken) &&
                      (path.StartsWithSegments("/connecthub")))
                  {
                    //  Read the token out of the query string
                      context.Token = accessToken;
                  }
                  return Task.CompletedTask;
              }
           };

       });

    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ApplicationDatabaseContext context)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseHttpsRedirection();

        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthentication();

        app.UseAuthorization();

        app.UseCors(CorsPolicy);

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
            endpoints.MapHub<signalR_Hub>("/connecthub");
        });


       }
    }
}

这是我的集线器连接

[Authorize]
public class sample_Hub :Hub
{
}

这是我的控制器

    [Authorize]
    [HttpPut("{id}")]
    public async Task<IActionResult> Putfilecreations(string id, filecreations filecreations)
    {
        var entity = _context.file_creations.Where(x => x.file_creation_id == id).FirstOrDefault();
        entity.client_type_id = filecreations.client_type_id;

         _context.file_creations.Update(entity);
        await _context.SaveChangesAsync();

        await _hubContext.Clients.All.SendAsync("FileUpdated", entity);
        return Ok(entity);
    }

这是我用于连接集线器的 Angular 代码

   this.hubConnection = new HubConnectionBuilder()
  .withUrl(environment.baseUrls.server + 'connecthub')
  .configureLogging(LogLevel.Information)
  .build(); 

标签: c#angularasp.net-coresignalr

解决方案


尝试以CORS这种方式添加,顺序很重要:

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

推荐阅读