尚未为此应用程序配置会话或使用 IHttpContextAccessor 时请求错误
Session has not been configured for this application or request Error when using IHttpContextAccessor
我在 .NET 6 Core 中创建了自定义授权策略。它可以很好地满足我的要求,但是我在调试时发现错误 - 尚未为此应用程序或请求配置会话。但是我已经在 program.cs 中配置了会话。如果在调试中显示此错误,是否还需要为会话配置一些内容?
调试错误截图:https://pasteboard.co/RuiKarjvJPuP.png
授权处理程序:
using Microsoft.AspNetCore.Authorization;
namespace myApp.Security
{
public class CrudAccessHandler : AuthorizationHandler<AccessRequirement>
{
private readonly IHttpContextAccessor httpContextAccessor;
public CrudAccessHandler(IHttpContextAccessor httpContextAccessor)
{
this.httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));
}
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, AccessRequirement requirement)
{
string? controllerName = httpContextAccessor.HttpContext?.Request.RouteValues["controller"]?.ToString();
string? actionName = httpContextAccessor.HttpContext?.Request.RouteValues["action"]?.ToString();
if (controllerName != null && actionName != null)
{
if (context.User.HasClaim(claim => (claim.Type == controllerName && claim.Value == actionName)))
{
context.Succeed(requirement);
}
}
if (controllerName != null && actionName == "Index")
{
if (context.User.HasClaim(claim => (claim.Type == controllerName && claim.Value == "Read")))
{
context.Succeed(requirement);
}
}
if (controllerName != null && actionName == "Clone")
{
if (context.User.HasClaim(claim => (claim.Type == controllerName && claim.Value == "Create")))
{
context.Succeed(requirement);
}
}
return Task.CompletedTask;
}
}
}
Program.cs:
using myApp.Data;
using MyApp.Interfaces;
using MyApp.Models;
using MyApp.Security;
using MyApp.Services;
using MyApp.Utilities;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddDbContextPool<ApplicationDbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
builder.Services.AddIdentity<ApplicationUser, ApplicationRole>().AddEntityFrameworkStores<ApplicationDbContext>().AddDefaultTokenProviders().AddDefaultUI();
builder.Services.AddTransient<IEmailSender, MailSender>();
builder.Services.Configure<IdentityOptions>(options =>
{
options.Password.RequiredLength = 8;
});
builder.Services.AddDistributedMemoryCache();
builder.Services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromMinutes(30);
options.Cookie.HttpOnly = true;
options.Cookie.IsEssential = true;
}
);
builder.Services.ConfigureApplicationCookie(options =>
{
options.LoginPath = "/Account/Login";
});
builder.Services.AddControllersWithViews(options =>
{
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
});
builder.Services.Configure<DataProtectionTokenProviderOptions>(options =>
{
options.TokenLifespan = TimeSpan.FromMinutes(5);
});
builder.Services.AddAuthorization(options =>
{
options.AddPolicy(Helper.AccessPolicy, policy => policy.AddRequirements(new CrudAccessRequirement()));
options.FallbackPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
});
builder.Services.AddTransient<IAuthorizationHandler, SuperAdminHandler>();
builder.Services.AddTransient<IAuthorizationHandler, CrudAccessHandler>();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseSession();
app.MapControllerRoute(name: "default", pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
我通过如下更改 HTTP 请求管道顺序解决了我的问题:
app.UseRouting();
app.UseSession();
app.UseAuthentication();
app.UseAuthorization();
这解决了我的 .NET 6 Core 问题
我在 .NET 6 Core 中创建了自定义授权策略。它可以很好地满足我的要求,但是我在调试时发现错误 - 尚未为此应用程序或请求配置会话。但是我已经在 program.cs 中配置了会话。如果在调试中显示此错误,是否还需要为会话配置一些内容?
调试错误截图:https://pasteboard.co/RuiKarjvJPuP.png
授权处理程序:
using Microsoft.AspNetCore.Authorization;
namespace myApp.Security
{
public class CrudAccessHandler : AuthorizationHandler<AccessRequirement>
{
private readonly IHttpContextAccessor httpContextAccessor;
public CrudAccessHandler(IHttpContextAccessor httpContextAccessor)
{
this.httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));
}
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, AccessRequirement requirement)
{
string? controllerName = httpContextAccessor.HttpContext?.Request.RouteValues["controller"]?.ToString();
string? actionName = httpContextAccessor.HttpContext?.Request.RouteValues["action"]?.ToString();
if (controllerName != null && actionName != null)
{
if (context.User.HasClaim(claim => (claim.Type == controllerName && claim.Value == actionName)))
{
context.Succeed(requirement);
}
}
if (controllerName != null && actionName == "Index")
{
if (context.User.HasClaim(claim => (claim.Type == controllerName && claim.Value == "Read")))
{
context.Succeed(requirement);
}
}
if (controllerName != null && actionName == "Clone")
{
if (context.User.HasClaim(claim => (claim.Type == controllerName && claim.Value == "Create")))
{
context.Succeed(requirement);
}
}
return Task.CompletedTask;
}
}
}
Program.cs:
using myApp.Data;
using MyApp.Interfaces;
using MyApp.Models;
using MyApp.Security;
using MyApp.Services;
using MyApp.Utilities;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddDbContextPool<ApplicationDbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
builder.Services.AddIdentity<ApplicationUser, ApplicationRole>().AddEntityFrameworkStores<ApplicationDbContext>().AddDefaultTokenProviders().AddDefaultUI();
builder.Services.AddTransient<IEmailSender, MailSender>();
builder.Services.Configure<IdentityOptions>(options =>
{
options.Password.RequiredLength = 8;
});
builder.Services.AddDistributedMemoryCache();
builder.Services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromMinutes(30);
options.Cookie.HttpOnly = true;
options.Cookie.IsEssential = true;
}
);
builder.Services.ConfigureApplicationCookie(options =>
{
options.LoginPath = "/Account/Login";
});
builder.Services.AddControllersWithViews(options =>
{
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
});
builder.Services.Configure<DataProtectionTokenProviderOptions>(options =>
{
options.TokenLifespan = TimeSpan.FromMinutes(5);
});
builder.Services.AddAuthorization(options =>
{
options.AddPolicy(Helper.AccessPolicy, policy => policy.AddRequirements(new CrudAccessRequirement()));
options.FallbackPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
});
builder.Services.AddTransient<IAuthorizationHandler, SuperAdminHandler>();
builder.Services.AddTransient<IAuthorizationHandler, CrudAccessHandler>();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseSession();
app.MapControllerRoute(name: "default", pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
我通过如下更改 HTTP 请求管道顺序解决了我的问题:
app.UseRouting();
app.UseSession();
app.UseAuthentication();
app.UseAuthorization();
这解决了我的 .NET 6 Core 问题