我按照官方文档从CustomClaimsTransformer中的自定义组件访问HttpContext。背景,我以前有一个.net核心Web应用程序,我使用该会话使管理员能够使用不同用户的视图(身份)跳转到应用程序(出于支持目的)。我存储信息,应该在会话中为哪个用户准备视图。现在我想让它更优雅,并使用声明和基于角色的授权使用.net核心授权。由于后面有Windows身份验证,我将使用CustomClaimsTransformer。现在我的问题是,我想从CustomClaimsTransformer中访问当前会话。我可以注入IHttpContextAccessor,但IHttpContextAccessor.Session总是引发无效的操作异常。
Startup.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:
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."
任何帮助都非常感谢
编辑1:
我在上面编辑了我的ConfigureServices,在粘贴代码时我删除了一些可读性的行,包括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?}");
});
}
参考Session and app state in ASP.NET Core
要启用会话中间件,
Startup
必须包含:
- 任何
IDistributedCache
内存缓存。IDistributedCache
实现用作会话的后备存储。- 在
AddSession
打电话给ConfigureServices
。- 在
UseSession
打电话给Configure
。
也
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
之后调用UseSession
时会发生UseMvc
异常。 ... 在调用HttpContext.Session
之前无法访问UseSession
。