【发布时间】:2021-03-11 22:24:01
【问题描述】:
我的 statup.cs 类代码如下所示:
namespace Tenet.eReserve.Api.WebApi
{
public class Startup
{
public IConfiguration Configuration { get; }
public string SuperSecret { get; set; }
public Startup(IConfiguration configuration) => Configuration = configuration;
public void ConfigureServices(IServiceCollection services)
{
services.AddOptions();
services.AddSingleton<IConfiguration>(Configuration);
services.Configure<Settings>(Configuration.GetSection("eReserve"));
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "eReserve API List", Version = "v1" });
c.AddSecurityDefinition("Bearer",
new OpenApiSecurityScheme
{
Description = "JWT Authorization header using the Bearer scheme.",
Type = SecuritySchemeType.Http, //We set the scheme type to http since we're using bearer authentication
Scheme = "bearer"
});
c.AddSecurityRequirement(new OpenApiSecurityRequirement{
{
new OpenApiSecurityScheme{
Reference = new OpenApiReference{
Id = "Bearer", //The name of the previously defined security scheme.
Type = ReferenceType.SecurityScheme
}
},new List<string>()
}
});
});
services.AddControllers().AddJsonOptions(options =>
{
options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
}).AddNewtonsoftJson(); // to convert string values to int32 and decimal
services.AddScoped<IReportService, ReportService>();
services.AddScoped<ISearchService, SearchService>();
var sp = services.BuildServiceProvider();
// This will succeed.
var settings = sp.GetService<IOptionsSnapshot<Settings>>();
services.AddApplicationInsightsTelemetry(options =>
{
options.EnableDebugLogger = false;
});
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder.WithOrigins(settings.Value.SignalROrigniURL) //http://localhost:8090")
.AllowAnyHeader()
.AllowAnyMethod()
.SetIsOriginAllowed((x) => true)
.AllowCredentials());
// options.AddPolicy("CorsPolicy",
// builder => builder.AllowAnyOrigin()
//.AllowAnyMethod()
//.AllowAnyHeader());
});
services.AddAuthentication(opt =>
{
opt.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
opt.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(
);
services.ConfigureOptions<ConfigureJwtBearerOptions>();
services.AddHttpContextAccessor();
services.AddAuthorization(options =>
{
options.AddPolicy("HospitalCode", policy =>
policy.Requirements.Add(new HospitalCodeRequirement()));
});
services.AddSingleton<IAuthorizationHandler, FacilityHandler>();
services.AddSignalR(options =>
{
options.EnableDetailedErrors = true;
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, TelemetryConfiguration configuration, IOptionsSnapshot<Settings> settings)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseAzureAppConfiguration();
app.UseSwagger();
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
// specifying the Swagger JSON endpoint.
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "eReserve API V1");
c.RoutePrefix = String.Empty;
});
configuration.InstrumentationKey = settings.Value.AppInsightsInstrumentationKey;
app.UseHttpsRedirection();
app.UseRouting();
app.UseCors("CorsPolicy");
app.UseAuthentication(); // this one first
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapHub<NotifyClientService>("/lockNotification");
});
//app.UseSignalR(routes =>
//{
// routes.MapHub<NotifyClientService>("/lockNotification");
//});
}
}
}
在角度上,我正在创建这样的连接:
private hubConnection: signalR.HubConnection;
public startConnection = () => {
this.hubConnection = new signalR.HubConnectionBuilder()
.withUrl(this.apiBase + 'lockNotification')
.build();
this.hubConnection
.start()
.then(() => console.log('Connection started'))
.catch(err => console.log('Error while starting connection: ' + err));
}
public startListener = () => {
this.hubConnection.on('LockNotification', (facilityName, lockType, hospitalCode) => {
//logic
}
});
}
这种安排在本地工作,但在部署时会出现 CORS 错误:
CORS 政策已阻止访问来自源“https://abc-ui.com”的“https://abc-api.com/lockNotification/negotiate?negotiateVersion=1”获取:响应预检请求未通过访问控制检查:响应中“Access-Control-Allow-Credentials”标头的值为“”,当请求的凭据模式为“包含”时,该值必须为“真”。 zone.js:1118 POST https://xxx-xxx.com/lockNotification/negotiate?negotiateVersion=1 net::ERR_FAILED
请注意“settings.Value.SignalROrigniURL”返回“https://abc-ui.com”(假网址)
更新
在 ConfigureServices 方法中,我有这样的 Cors:
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader());
});
不确定是否需要上述内容,并且在配置中我遵循了文档。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, TelemetryConfiguration configuration, IOptionsSnapshot<Settings> settings)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseAzureAppConfiguration();
app.UseSwagger();
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
// specifying the Swagger JSON endpoint.
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "eReserve API V1");
c.RoutePrefix = String.Empty;
});
configuration.InstrumentationKey = settings.Value.AppInsightsInstrumentationKey;
app.UseHttpsRedirection();
app.UseCors(builder =>
{
builder.WithOrigins(settings.Value.SignalROrigniURL)
.AllowAnyHeader()
.WithMethods("GET", "POST")
.AllowCredentials();
});
app.UseRouting();
app.UseAuthentication(); // this one first
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapHub<NotifyClientService>("/lockNotification");
});
//app.UseSignalR(routes =>
//{
// routes.MapHub<NotifyClientService>("/lockNotification");
//});
}
更新 2
CORS 也在部署 api 的位置进行配置。
【问题讨论】:
-
您是否尝试过 doc 中的配置? docs.microsoft.com/en-us/aspnet/core/signalr/…
-
我根据文档添加了更新。同样的错误。但是,文档没有说明“ConfigureServices”方法。
-
您在哪里部署了您的应用程序?您可能需要在部署中配置 CORS,例如 Azure App Service 具有在门户中配置 CORS 的选项。
-
好的,调查一下
-
查看更新2.好像配置好了。
标签: angular asp.net-core signalr