【发布时间】:2018-02-22 02:24:13
【问题描述】:
我有一个无法解决的重大问题。我有一个带有 jwt auth 的.net core 2 项目,并试图让一个基本的信号器集线器测试工作。来自客户端的连接似乎可以正常工作,但连接会立即断开,并出现 204 代码。
我的集线器在我的前端 UI 之外的另一个 URL 上运行,因此涉及到 CORS。
**我删除了真实密钥和我的项目名称
这是客户端控制台输出的内容:
这是我的启动代码:
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.Configure<ConnectionStrings>(Configuration.GetSection("ConnectionStrings"));
services.Configure<DiAssemblies>(Configuration.GetSection("DiAssemblies"));
services.Configure<StripeSettings>(Configuration.GetSection("Stripe"));
services.Configure<AzureStorageSettings>(Configuration.GetSection("AzureStorageSettings"));
// Add framework services.
services.AddApplicationInsightsTelemetry(Configuration);
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
x => x.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
services.AddCors();
services.AddIdentity<testApp.Identity.ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<testApp.Identity.Context>()
.AddDefaultTokenProviders();
services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
sharedOptions.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
sharedOptions.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.RequireHttpsMetadata = false;
options.SaveToken = true;
options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters()
{
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("authkeyasdfasdfasdfsadfasdfda")),
ValidIssuer = "https://testApp.com/",
ValidAudience = "https://testApp.com/",
};
options.Events = new JwtBearerEvents
{
OnAuthenticationFailed = context =>
{
Debug.WriteLine("Auth issue");
Debug.WriteLine(context.Exception);
return Task.CompletedTask;
},
OnMessageReceived = context =>
{
if (!context.Request.Headers.ContainsKey("Authorization") && !string.IsNullOrEmpty(context.Request.Query["authToken"]))
{
context.Request.Headers.Add("Authorization", context.Request.Query["authToken"]);
}
return Task.CompletedTask;
},
OnChallenge = context =>
{
Debug.WriteLine("Auth issue");
Debug.WriteLine(context.Error);
Debug.WriteLine(context.ErrorDescription);
return Task.CompletedTask;
}
};
});
services.AddMemoryCache();
services.AddMvc().AddJsonOptions(options =>
{
options.SerializerSettings.ContractResolver =
new CamelCasePropertyNamesContractResolver();
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
});
services.AddSockets();
services.AddSignalRCore();
var builder = new ContainerBuilder();
// Register dependencies, populate the services from
// the collection, and build the container. If you want
// to dispose of the container at the end of the app,
// be sure to keep a reference to it as a property or field.
//builder.RegisterType<MyType>().As<IMyType>();
builder.Populate(services);
var diHelper = new DiHelper();
var diAssemblies = Configuration.GetValue<string>("DiAssemblies:List");
var assemblies = diHelper.GetAssemblies(diAssemblies.Split(',').ToList());
// Console.Write(diAssemblies);
builder.RegisterAssemblyModules(assemblies);
ApplicationContainer = builder.Build();
//foreach(var assembly in assemblies)
// services.AddMvc().AddApplicationPart(assembly).AddControllersAsServices();
// Create the IServiceProvider based on the container.
return new AutofacServiceProvider(ApplicationContainer);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseCors(
options => options.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader()
);
app.UseAuthentication();
app.UseMvc();
app.UseSignalR(routes =>
{
routes.MapHub<ChatHub>("chat");
});
}
}
我的 Hub(任何方法的断点都不会被命中)
public class ChatHub : Hub
{
public ChatHub()
{
var t = 0;
}
public override async Task OnConnectedAsync()
{
await Clients.Client(Context.ConnectionId).InvokeAsync("send", "connection made");
await base.OnConnectedAsync();
}
public Task Send(string message)
{
return Clients.All.InvokeAsync("send", message);
}
}
客户端javascript:
<script>
window.connection;
window.connection = new signalR.HubConnection("https://localhost:44367/chat?authToken=" + 'bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.yyJzdWIiOiJhYzNkMTU3OC05YjU5LTRmNzQtOWMxYi01MWZlYjk2YmQ4YzEiLCJqdGkiOiJidnRlc3QxIiwiZXhwIjoxTYI2NjY1OTM3LCJpc3MiOiJodHRwczovL2Jpc3ZpbmUuY29tLyIsImF1ZCI6Imh0dHBzOi1vYmlzdmluZS5jb20vIn0.GxycqmyVsdHkW3M5yRH7arGkR3K-jAE2zrPrgoJnh-M',
{ transport: signalR.TransportType.LongPolling });
window.connection.on('send', function(message) {
alert(message);
});
window.connection.start().then(function() {
console.log("SignalR Connected: Chat");
window.connection.invoke('send',"hi").then(function (chats) {
console.log(chats);
});
}, function () {
});
</script>
【问题讨论】:
-
能不能去掉传输:signalR.TransportType.LongPolling
-
没有信号器 2 要求您设置传输
-
Signalr 2 或 .net core 2。为什么你默认使用长轮询而不是使用 web 套接字?
-
在 Windows 7 上测试
-
嗯,让我检查一下我的项目,看看是否有不同之处。您的身份验证中间件在哪里拦截您的 get 参数并将其转换为 jwt?