У меня есть доверенный сервер, который должен иметь возможность отправлять почтовый запрос с HMAC и идентификатором пользователя на мой сервер (оба сервера имеют одну и ту же базу данных с одними и теми же пользователями), чтобы пользователю не приходилось снова входить в систему. У меня есть промежуточное программное обеспечение для защиты от подделки (оно крайне необходимо для безопасности), которое должно работать в части приложения Blazor, но не в API и контроллерах. Я пробовал много решений, но ни одно не помогло.
Решения, которые я пробовал:
Отключение защиты от подделки через program.cs:
app.MapControllers().DisableAntiforgery();
services.AddAntiforgery(options =>
{
options.HeaderName = "X-CSRF-TOKEN";
});
app.Use(async (context, next) =>
{
var path = context.Request.Path.Value?.ToLowerInvariant() ?? "";
if (path.Contains("/account/loginviatrustedserver"))
{
await next();
return;
}
var antiforgery = context.RequestServices.GetRequiredService();
if (HttpMethods.IsPost(context.Request.Method) ||
HttpMethods.IsPut(context.Request.Method) ||
HttpMethods.IsDelete(context.Request.Method) ||
HttpMethods.IsPatch(context.Request.Method))
{
await antiforgery.ValidateRequestAsync(context);
}
await next();
});
Отключение защиты от подделки в конечных точках минимального API:
endpoints.MapPost(logic)..DisableAntiforgery()
.WithMetadata(new IgnoreAntiforgeryTokenAttribute());
Переписываем эту конкретную конечную точку в контроллер и добавляем атрибуты:
[ApiController]
[Route("Account/[action]")]
[IgnoreAntiforgeryToken]
[AllowAnonymous]
public partial class AccountController()
{
[IgnoreAntiforgeryToken]
public async Task LoginViaTrustedServer()
{ }
}
Ни один из этих подходов не сработал, и я все равно получаю сообщение об ошибке:
В запросе не был предоставлен действительный токен защиты от подделки. Добавьте токен защиты от подделки или отключите проверку защиты от подделки для этой конечной точки.
Моя программа.cs:
var builder = WebApplication.CreateBuilder(args);
builder.Services
.AddBlazorComponents()
.AddUiLibraries()
.AddDatabase(builder.Configuration)
.AddAuth(builder.Configuration)
.AddApplicationServices()
.AddRadzenConfiguration();
var app = builder.Build();
app.ConfigurePipeline();
app.Run();
public static class WebApplicationExtensions
{
public static WebApplication ConfigurePipeline(this WebApplication app)
{
var forwardingOptions = new ForwardedHeadersOptions()
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
};
forwardingOptions.KnownIPNetworks.Clear();
forwardingOptions.KnownProxies.Clear();
app.UseForwardedHeaders(forwardingOptions);
// 2. Exception Handling и HSTS
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error", createScopeForErrors: true);
app.UseHsts();
}
app.UseStatusCodePagesWithReExecute("/not-found");
app.UseHttpsRedirection();
app.MapStaticAssets();
app.UseRouting();
// 6. Localization (после routing, до authentication)
app.UseRequestLocalization(options =>
options.AddSupportedCultures("ky", "ru")
.AddSupportedUICultures("ky", "ru")
.SetDefaultCulture("ky")
);
// 7. Authentication & Authorization
app.UseAuthentication();
app.UseAuthorization();
app.UseAntiforgery();
// 9. Endpoints
app.MapRiaLoginEndpoint();
app.MapRazorComponents().AddInteractiveServerRenderMode();
app.MapControllers();
return app;
}
}
public static class ServiceExtensions
{
public static IServiceCollection AddBlazorComponents(this IServiceCollection services)
{
services.AddRazorComponents()
.AddInteractiveServerComponents()
.AddHubOptions(options => options.MaximumReceiveMessageSize = 10 * 1024 * 1024);
services.AddCascadingAuthenticationState();
return services;
}
public static IServiceCollection AddDatabase(this IServiceCollection services, IConfiguration configuration)
{
services.Configure(configuration.GetSection("DatabaseSettings"));
var dbSettings = configuration.GetSection("DatabaseSettings").Get();
var connectionStringKey = dbSettings?.UseTestDb == true
? "TestConnection"
: "ProductionConnection";
services.AddDbContextFactory(options =>
options.UseSqlServer(configuration.GetConnectionString(connectionStringKey)));
return services;
}
public static IServiceCollection AddAuth(this IServiceCollection services, IConfiguration config)
{
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(options =>
{
options.LoginPath = "/login";
options.LogoutPath = "/logout";
options.ExpireTimeSpan = TimeSpan.FromDays(1);
options.AccessDeniedPath = "/access-denied";
options.SlidingExpiration = true;
options.Cookie.HttpOnly = true;
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
options.Cookie.SameSite = SameSiteMode.Lax;
});
services.AddOptions()
.BindConfiguration("AuthSettings")
.Validate(x => !string.IsNullOrWhiteSpace(x.SharedSecretBase64), "SharedSecretBase64 is required")
.Validate(x =>
{
try
{
x.SharedSecret = Convert.FromBase64String(x.SharedSecretBase64);
return true;
}
catch
{
return false;
}
}, "SharedSecretBase64 must be valid Base64")
.ValidateOnStart();
services.AddAuthorization();
services.AddHttpContextAccessor();
services.AddScoped();
return services;
}
public static IServiceCollection AddApplicationServices(this IServiceCollection services)
{
services.AddControllers(options =>
{
options.Filters.Clear();
});
services.AddHttpClient();
services.AddLocalization();
services.AddScoped();
return services;
}
public static IServiceCollection AddRadzenConfiguration(this IServiceCollection services)
{
services.AddRadzenComponents();
services.AddRadzenCookieThemeService(options =>
{
options.Name = "gg";
options.Duration = TimeSpan.FromDays(365);
});
return services;
}
public static IServiceCollection AddUiLibraries(this IServiceCollection services)
{
services.AddMudServices();
return services;
}
}
Подробнее здесь: https://stackoverflow.com/questions/798 ... -endpoints
Невозможно отключить защиту от подделки для конечных точек ⇐ C#
Место общения программистов C#
-
Anonymous
1766040335
Anonymous
У меня есть доверенный сервер, который должен иметь возможность отправлять почтовый запрос с HMAC и идентификатором пользователя на мой сервер (оба сервера имеют одну и ту же базу данных с одними и теми же пользователями), чтобы пользователю не приходилось снова входить в систему. У меня есть промежуточное программное обеспечение для защиты от подделки (оно крайне необходимо для безопасности), которое должно работать в части приложения Blazor, но не в API и контроллерах. Я пробовал много решений, но ни одно не помогло.
Решения, которые я пробовал:
Отключение защиты от подделки через program.cs:
app.MapControllers().DisableAntiforgery();
services.AddAntiforgery(options =>
{
options.HeaderName = "X-CSRF-TOKEN";
});
app.Use(async (context, next) =>
{
var path = context.Request.Path.Value?.ToLowerInvariant() ?? "";
if (path.Contains("/account/loginviatrustedserver"))
{
await next();
return;
}
var antiforgery = context.RequestServices.GetRequiredService();
if (HttpMethods.IsPost(context.Request.Method) ||
HttpMethods.IsPut(context.Request.Method) ||
HttpMethods.IsDelete(context.Request.Method) ||
HttpMethods.IsPatch(context.Request.Method))
{
await antiforgery.ValidateRequestAsync(context);
}
await next();
});
Отключение защиты от подделки в конечных точках минимального API:
endpoints.MapPost(logic)..DisableAntiforgery()
.WithMetadata(new IgnoreAntiforgeryTokenAttribute());
Переписываем эту конкретную конечную точку в контроллер и добавляем атрибуты:
[ApiController]
[Route("Account/[action]")]
[IgnoreAntiforgeryToken]
[AllowAnonymous]
public partial class AccountController()
{
[IgnoreAntiforgeryToken]
public async Task LoginViaTrustedServer()
{ }
}
Ни один из этих подходов не сработал, и я все равно получаю сообщение об ошибке:
В запросе не был предоставлен действительный токен защиты от подделки. Добавьте токен защиты от подделки или отключите проверку защиты от подделки для этой конечной точки.
Моя программа.cs:
var builder = WebApplication.CreateBuilder(args);
builder.Services
.AddBlazorComponents()
.AddUiLibraries()
.AddDatabase(builder.Configuration)
.AddAuth(builder.Configuration)
.AddApplicationServices()
.AddRadzenConfiguration();
var app = builder.Build();
app.ConfigurePipeline();
app.Run();
public static class WebApplicationExtensions
{
public static WebApplication ConfigurePipeline(this WebApplication app)
{
var forwardingOptions = new ForwardedHeadersOptions()
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
};
forwardingOptions.KnownIPNetworks.Clear();
forwardingOptions.KnownProxies.Clear();
app.UseForwardedHeaders(forwardingOptions);
// 2. Exception Handling и HSTS
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error", createScopeForErrors: true);
app.UseHsts();
}
app.UseStatusCodePagesWithReExecute("/not-found");
app.UseHttpsRedirection();
app.MapStaticAssets();
app.UseRouting();
// 6. Localization (после routing, до authentication)
app.UseRequestLocalization(options =>
options.AddSupportedCultures("ky", "ru")
.AddSupportedUICultures("ky", "ru")
.SetDefaultCulture("ky")
);
// 7. Authentication & Authorization
app.UseAuthentication();
app.UseAuthorization();
app.UseAntiforgery();
// 9. Endpoints
app.MapRiaLoginEndpoint();
app.MapRazorComponents().AddInteractiveServerRenderMode();
app.MapControllers();
return app;
}
}
public static class ServiceExtensions
{
public static IServiceCollection AddBlazorComponents(this IServiceCollection services)
{
services.AddRazorComponents()
.AddInteractiveServerComponents()
.AddHubOptions(options => options.MaximumReceiveMessageSize = 10 * 1024 * 1024);
services.AddCascadingAuthenticationState();
return services;
}
public static IServiceCollection AddDatabase(this IServiceCollection services, IConfiguration configuration)
{
services.Configure(configuration.GetSection("DatabaseSettings"));
var dbSettings = configuration.GetSection("DatabaseSettings").Get();
var connectionStringKey = dbSettings?.UseTestDb == true
? "TestConnection"
: "ProductionConnection";
services.AddDbContextFactory(options =>
options.UseSqlServer(configuration.GetConnectionString(connectionStringKey)));
return services;
}
public static IServiceCollection AddAuth(this IServiceCollection services, IConfiguration config)
{
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(options =>
{
options.LoginPath = "/login";
options.LogoutPath = "/logout";
options.ExpireTimeSpan = TimeSpan.FromDays(1);
options.AccessDeniedPath = "/access-denied";
options.SlidingExpiration = true;
options.Cookie.HttpOnly = true;
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
options.Cookie.SameSite = SameSiteMode.Lax;
});
services.AddOptions()
.BindConfiguration("AuthSettings")
.Validate(x => !string.IsNullOrWhiteSpace(x.SharedSecretBase64), "SharedSecretBase64 is required")
.Validate(x =>
{
try
{
x.SharedSecret = Convert.FromBase64String(x.SharedSecretBase64);
return true;
}
catch
{
return false;
}
}, "SharedSecretBase64 must be valid Base64")
.ValidateOnStart();
services.AddAuthorization();
services.AddHttpContextAccessor();
services.AddScoped();
return services;
}
public static IServiceCollection AddApplicationServices(this IServiceCollection services)
{
services.AddControllers(options =>
{
options.Filters.Clear();
});
services.AddHttpClient();
services.AddLocalization();
services.AddScoped();
return services;
}
public static IServiceCollection AddRadzenConfiguration(this IServiceCollection services)
{
services.AddRadzenComponents();
services.AddRadzenCookieThemeService(options =>
{
options.Name = "gg";
options.Duration = TimeSpan.FromDays(365);
});
return services;
}
public static IServiceCollection AddUiLibraries(this IServiceCollection services)
{
services.AddMudServices();
return services;
}
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79850013/cant-disable-antiforgery-for-endpoints[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия