CustomClaimsTransformer 中的 IHttpContextAccessor 会话无效操作异常



我按照官方文档从CustomClaimsTransformer中的自定义组件访问HttpContext。

我以前有一个 .NET Core Web 应用程序,我使用该会话使管理员能够使用其他用户的视图(标识(跳转到应用程序(出于支持目的(。我存储信息,应在会话中为哪个用户准备视图。现在,我想使它更加优雅,并通过声明和基于角色的授权使用 .net 核心授权。由于后面有一个Windows身份验证,我必须使用CustomClaimsTransformer。现在我的问题是,我想从自定义声明转换器中访问当前会话。我可以注入 IHttpContextAccessor,但 IHttpContextAccessor.Session 总是引发无效操作异常。

启动.cs:

public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme,
options =>
{
options.LoginPath = new PathString("/Account/Login/");
options.AccessDeniedPath = new PathString("/Account/Forbidden/");
});
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddAuthorization(options =>
{
options.AddPolicy("RequireAdministratorRole", policy => policy.RequireClaim(ClaimTypes.Role, "admin"));
options.AddPolicy("Test1", policy => policy.RequireClaim("Rechte", " Test1"));
options.AddPolicy("Test2", policy => policy.RequireClaim("Rechte", " Test2"));
});
services.AddMvc(config =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
config.Filters.Add(new AuthorizeFilter(policy));
}).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
//services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddHttpContextAccessor();
services.AddTransient<IClaimsTransformation, CustomClaimsTransformer>();
services.AddDistributedMemoryCache();
services.AddSession();
}

自定义声明转换器:

CustomClaimsTransformer:
public class CustomClaimsTransformer : IClaimsTransformation
{
private readonly IHttpContextAccessor _httpContextAccessor;
public CustomClaimsTransformer(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}

public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
var z = _httpContextAccessor.HttpContext; //works
var zz = _httpContextAccessor.HttpContext.Session; // System.InvalidOperationException: "Session has not been configured for this application or request."

我在上面编辑了我的配置服务,在粘贴代码时,为了便于阅读,我删除了一些行,包括 AddDistributedMemoryCache 行,抱歉。会话在应用程序中工作,除非显示的位置。

配置:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseSession();
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}

核心 ASP.NET 中的引用会话和应用状态

要启用会话中间件,Startup必须包含:

  • 任何IDistributedCache内存缓存。IDistributedCache实现用作 会期。
  • ConfigureServices中呼唤AddSession.
  • Configure中呼唤UseSession.

public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
//... removed for brevity
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseSession(); // This must come before "UseMvc()"
app.UseHttpContextItemsMiddleware();
app.UseMvc();
}

中间件的顺序很重要。在前面的示例中,一个InvalidOperationException异常发生在UseSessionUseMvc之后调用。

在调用UseSession之前无法访问HttpContext.Session

相关内容

最新更新