#asp.net-core #identityserver4 #blazor #blazor-webassembly
#asp.net-ядро #identityserver4 #blazor #blazor-webassembly
Вопрос:
У меня есть проект blazor WASM, который отлично работает при разработке и локальном производстве (на моем компьютере), но не на производственном сервере Linux. Когда я публикую проект на рабочем сервере (Ubuntu 20.04), проект продолжает отправлять запросы (только на клиенте, а не на сервере)
Что это может быть? Я не устанавливал SSL-сертификат, поэтому все запросы являются http, а не https.
https://gfycat.com/reliablefarawaycurlew
Program.cs в клиентском проекте
public class Program
{
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
builder.Services.AddHttpClient("BlazorAppManagerWeb.ServerAPI", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
.AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
builder.Services.AddSingleton(new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
ConfiguteServices(builder.Services);
var host = builder.Build();
var js = host.Services.GetRequiredService<IJSRuntime>();
//var culture = await js.InvokeAsync<string>("getFromLocalStorage", "culture");
string culture = null;
CultureInfo selectedCulture;
if (culture == null)
{
selectedCulture = new CultureInfo("he-IL");
}
else
{
selectedCulture = new CultureInfo(culture);
}
CultureInfo.DefaultThreadCurrentCulture = selectedCulture;
CultureInfo.DefaultThreadCurrentUICulture = selectedCulture;
await host.RunAsync();
}
public static void ConfiguteServices(IServiceCollection services)
{
services.AddLocalization();
services.AddScoped<IHttpService, HttpService>();
services.AddScoped<Repository.IEntityRepository, Repository.EntityRepository>();
services.AddScoped<IMyVehicleRepository, MyVehicleRepository>();
services.AddScoped<IMyVehicleCommentRepository, MyVehicleCommentRepository>();
services.AddScoped<IVehicleTypeRepository, VehicleTypeRepository>();
services.AddScoped<IVehicleManufacturerRepository, VehicleManufacturerRepository>();
services.AddScoped<IVehicleModelRepository, VehicleModelRepository>();
services.AddScoped<IMyVehicleStatusRepository, MyVehicleStatusRepository>();
services.AddScoped<IDocumentRepository, DocumentRepository>();
services.AddScoped<IItemRepository, ItemRepository>();
services.AddScoped<IMissionRepository, MissionRepository>();
services.AddScoped<ICustomerVehicleRepository, CustomerVehicleRepository>();
services.AddScoped<ICustomerVehicleStatusRepository, CustomerVehicleStatusRepository>();
services.AddScoped<IMissionCardRepository, MissionCardRepository>();
services.AddScoped<IBankRepository, BankRepository>();
services.AddScoped<IDepositRepository, DepositRepository>();
services.AddScoped<IGeneralRepository, GeneralRepository>();
services.AddScoped<IEntityCommentRepository, EntityCommentRepository>();
services.AddScoped<IEntityToDoRepository, EntityToDoRepository>();
services.AddScoped<ICalendarRepository, CalendarRepository>();
services.AddScoped<IReportsRepository, ReportsRepository>();
services.AddScoped<Repository.InSControl.IEntityRepository, Repository.InSControl.EntityRepository>();
services.AddScoped<IDisplayMessage, DisplayMessage>();
services.AddFileReaderService(options => options.InitializeOnFirstCall = true);
/* LOCALIZATION MANUALLY SET TO HEBREW
var culture = new CultureInfo("he-IL");
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;*/
// Supply HttpClient instances that include access tokens when making requests to the server project
services.AddTransient(sp => sp.GetRequiredService<IHttpClientFactory>().CreateClient("BlazorAppManagerWeb.ServerAPI"));
services.AddApiAuthorization();
}
}
Program.cs на сервере
public class Program
{
public static void Main(string[] args)
{
var webHost = CreateHostBuilder(args).Build();
using(var scope = webHost.Services.CreateScope())
{
var services = scope.ServiceProvider;
var context = services.GetService<ApplicationDbContext>();
context.Database.Migrate();
var context2 = services.GetService<ControlDbContext>();
context2.Database.Migrate();
}
webHost.Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
Startup.cs в клиентском проекте
public class Startup
{
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.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>();
services.AddDbContext<ControlDbContext>(options =>
{
options.UseSqlServer(
Configuration.GetConnectionString("ControlConnection"));
});
services.AddDefaultIdentity<ApplicationUser>(options => {
options.SignIn.RequireConfirmedAccount = false;
options.Password.RequireDigit = false;
options.Password.RequireLowercase = false;
options.Password.RequireUppercase = false;
options.Password.RequireNonAlphanumeric = false;
})
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddTransient<IEmailSender, EmailSender>();
services.AddIdentityServer()
.AddApiAuthorization<ApplicationUser, ApplicationDbContext>();
services.ConfigureExternalCookie(options => {
options.Cookie.IsEssential = true;
options.Cookie.SameSite = SameSiteMode.Unspecified; //SameSiteMode.Unspecified in .NET Core 3.1
options.ExpireTimeSpan = TimeSpan.FromDays(365);
});
services.ConfigureApplicationCookie(options => {
options.Cookie.IsEssential = true;
options.Cookie.SameSite = SameSiteMode.Unspecified; //SameSiteMode.Unspecified in .NET Core 3.1
options.ExpireTimeSpan = TimeSpan.FromDays(365);
});
services.AddAuthentication()
.AddIdentityServerJwt();
services.AddAutoMapper(typeof(Startup));
services.AddScoped<IFileStorageService, InAppStorageService>();
services.AddHttpContextAccessor();
services.AddTransient<IUserRepository, UserRepository>();
services.AddTransient<IEntityRepository, EntityRepository>();
services.AddMvc().AddNewtonsoftJson(options=> options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
services.AddControllersWithViews();
services.AddRazorPages();
services.AddTransient<CustomerVehiclesController, CustomerVehiclesController>();
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("he-IL");
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
app.UseWebAssemblyDebugging();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseBlazorFrameworkFiles();
app.UseStaticFiles();
app.UseRouting();
app.UseIdentityServer();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapControllers();
endpoints.MapFallbackToFile("index.html");
});
}
}
Комментарии:
1. «продолжать отправлять запросы (только на клиенте, а не на сервере)» не очень понятно.
2. @HenkHolterman Решение Blazor WASM создано с использованием 3 проектов — клиентского, серверного и общего, страницы выполняются на клиенте, но поскольку я использую аутентификацию с использованием отдельных учетных записей пользователей, оно сгенерировало систему аутентификации в серверном проекте. когда я нахожусь на странице входа в систему, которая хранится в серверном проекте, у меня нет никаких проблем, но когда я нахожусь на страницах, связанных с клиентским проектом I, он продолжает отправлять запрос, как в gif, который я прикрепил к вопросу
3. Скорее всего: включить WebSockets на сервере prod.