我在 .NET Core Web API 中配置了 SignalR,如下所示。
using AutoMapper;
using Azure.Storage.Blobs;
using DinkToPdf;
using DinkToPdf.Contracts;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;
using Microsoft.Identity.Client;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using System;
using System.Reflection;
using System.Text;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder.AllowAnyMethod()
.SetIsOriginAllowed(_ => true)
.AllowAnyHeader()
.AllowCredentials());
});
builder.Services.AddScoped<IDapperWrapper, DapperWrapper>();
//Use below code for global authorization and add AllowAnonymous to login route.
//otherwise use Authorize in the required controller and/or action
builder.Services.AddControllers(options =>
{
options.Filters.Add(new AuthorizeFilter());
});
builder.Services.AddApiVersioning(x =>
{
x.DefaultApiVersion = new ApiVersion(1, 0);
x.AssumeDefaultVersionWhenUnspecified = true;
x.ReportApiVersions = true;
});
builder.Services.AddAntiforgery(antiforgeryOptions =>
{
antiforgeryOptions.HeaderName = "X-XSRF-TOKEN";
antiforgeryOptions.Cookie.HttpOnly = true;
antiforgeryOptions.Cookie.SecurePolicy = CookieSecurePolicy.Always;
});
#region --> JWT Authentication
builder.Services.Configure<JWTSettings>(options =>
{
builder.Configuration.GetSection("Jwt").Bind(options);
var securityKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(options.Secret));
options.ValidFor = TimeSpan.FromMinutes(Convert.ToInt32(builder.Configuration["Jwt:ValidFor"]));
options.SigningCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
});
JWTSettings jwtSettings = builder.Configuration.GetSection("Jwt").Get<JWTSettings>();
builder.Services.AddJWTAuthentication(jwtSettings);
#endregion
builder.Services.AddSingleton<CustomIDataProtection>();
builder.Services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools()));
builder.Services.AddSignalR(o => { o.EnableDetailedErrors = true; });
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseMiddleware<ExceptionMiddleware>();
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseRouting();
app.UseCors("CorsPolicy");
app.UseAntiforgeryToken();
app.UseAuthorization();
app.Use(async (context, next) =>
{
if (!context.Response.Headers.ContainsKey("X-Frame-Options"))
{
context.Response.Headers.Add("X-Frame-Options", "SAMEORIGIN");
}
await next();
});
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "api",
pattern: "{controller}/{action}/{id?}");
endpoints.MapControllerRoute(
name: "api",
pattern: "{controller}/{action}/{name}");
endpoints.MapControllerRoute(
name: "api",
pattern: "{controller}/{action}/{date}");
endpoints.MapControllerRoute(
name: "api",
pattern: "{controller}/{action}/{email}");
});
if (bool.Parse(builder.Configuration["UseSwagger"]))
{
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "API");
c.DefaultModelsExpandDepth(-1);
});
}
app.MapHub<HjsHub>("/hjsHub");
app.Run();
它与我的
localhost
完美配合。
Azure 应用服务托管我的 Web API。当我运行此代码并尝试连接 SignalR 时,我收到错误方法不允许。
Azure 是否需要任何配置,或者我的代码中是否缺少某些内容?
我已经在本地服务器中尝试了上面的代码,并在Azure应用程序服务上尝试过。
更新
请更改您的中间件顺序,如下所示并再次测试。
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseMiddleware<ExceptionMiddleware>();
app.UseHttpsRedirection();
//app.UseAuthentication();
app.UseRouting();
app.UseCors("CorsPolicy");
//app.UseAntiforgeryToken();
app.UseAuthentication();
app.UseAuthorization();
app.UseAntiforgeryToken();
app.Use(async (context, next) =>
{
if (!context.Response.Headers.ContainsKey("X-Frame-Options"))
{
context.Response.Headers.Add("X-Frame-Options", "SAMEORIGIN");
}
await next();
});
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "api",
pattern: "{controller}/{action}/{id?}");
endpoints.MapControllerRoute(
name: "api",
pattern: "{controller}/{action}/{name}");
endpoints.MapControllerRoute(
name: "api",
pattern: "{controller}/{action}/{date}");
endpoints.MapControllerRoute(
name: "api",
pattern: "{controller}/{action}/{email}");
});
if (bool.Parse(builder.Configuration["UseSwagger"]))
{
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "API");
c.DefaultModelsExpandDepth(-1);
});
}
app.MapHub<HjsHub>("/hjsHub");
app.Run();
您应该使用下面的代码来允许所有来源进行测试。
builder.Services.AddCors(options => options.AddPolicy("CorsPolicy", builder =>
{
builder.AllowAnyMethod()
.SetIsOriginAllowed(_ => true)
.AllowAnyHeader()
.AllowCredentials();
}));
如果您希望它适用于特定网址,请不要同时使用
WithOrigins
和 AllowAnyOrigin
。