c0y*_*teX 4 c# identity dependency-injection httpcontext clean-architecture
我正在尝试使用Jason Taylor 的 Clean Architecture Template,这个模板使用 NSwag 自动创建一个 TypeScript 客户端(Angular),但我不需要创建一个 TS 客户端,所以我的主要目标是用 Razor Pages 替换它。我已经能够做到这一点,但当CurrentUserService被实例化时,我遇到了问题,它应该在这一行中设置 UserId:
UserId = httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.NameIdentifier);
Run Code Online (Sandbox Code Playgroud)
这是完整的CurrentUserService:
using CleanREC0.Application.Common.Interfaces;
using Microsoft.AspNetCore.Http;
using System.Security.Claims;
namespace CleanREC0.WebUI.Services
{
public class CurrentUserService : ICurrentUserService
{
public CurrentUserService(IHttpContextAccessor httpContextAccessor)
{
UserId = httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.NameIdentifier);
}
public string UserId { get; }
}
}
Run Code Online (Sandbox Code Playgroud)
第一次甚至 HttpContext 为空,这很好,因为一切都在初始化,但随后的调用总是在所有httpContextAccessor.HttpContext.User.Identity属性上返回null,用户显示了一个身份,但它的所有属性和声明都是null或Yield no results,即使用户正确登录。
这是我对模板所做的事情的列表:
这是我的 StartUp 课程:
public class Startup
{
public Startup(IConfiguration configuration, IWebHostEnvironment environment)
{
Configuration = configuration;
Environment = environment;
}
public IConfiguration Configuration { get; }
public IWebHostEnvironment Environment { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddApplication();
services.AddInfrastructure(Configuration, Environment);
services.AddScoped<ICurrentUserService, CurrentUserService>();
services.AddHttpContextAccessor();
services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>(); //I have added this line on as suggested on other post, but made no difference.
services.AddHealthChecks()
.AddDbContextCheck<ApplicationDbContext>();
services.AddRazorPages()
.AddFluentValidation(fv => fv.RegisterValidatorsFromAssemblyContaining<IApplicationDbContext>());
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseCustomExceptionHandler();
app.UseHealthChecks("/health");
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
}
Run Code Online (Sandbox Code Playgroud)
这是从ConfigureServices调用的AddApplication:
public static IServiceCollection AddApplication(this IServiceCollection services)
{
services.AddAutoMapper(Assembly.GetExecutingAssembly());
services.AddMediatR(Assembly.GetExecutingAssembly());
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(RequestPerformanceBehaviour<,>));
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(RequestValidationBehavior<,>));
return services;
}
Run Code Online (Sandbox Code Playgroud)
以及也在那里被调用的AddInfrastructure:
public static IServiceCollection AddInfrastructure(this IServiceCollection services, IConfiguration configuration, IWebHostEnvironment environment)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
configuration.GetConnectionString("DefaultConnection"),
b => b.MigrationsAssembly(typeof(ApplicationDbContext).Assembly.FullName)));
services.AddScoped<IApplicationDbContext>(provider => provider.GetService<ApplicationDbContext>());
services.AddDefaultIdentity<ApplicationUser>()
.AddEntityFrameworkStores<ApplicationDbContext>();
if (environment.IsEnvironment("Test"))
{
}
else
{
services.AddTransient<IDateTime, DateTimeService>();
services.AddTransient<IIdentityService, IdentityService>();
services.AddTransient<ICsvFileBuilder, CsvFileBuilder>();
}
services.AddAuthentication();
return services;
}
Run Code Online (Sandbox Code Playgroud)
其他一切似乎都运行良好。在Razor 页面级别,用户变量及其身份包含所有预期信息和声明。
我确定我遗漏了一些东西,有人可以指出我正确的方向吗?
LinkedListT 在评论中的链接让我找到了正确的方向。
该链接指向一个解释这一点的答案:
在 ASP.NET MVC 框架下,当控制器类按照您的预期构建时,HttpContext(以及因此 HttpContext.Session)并未设置,但它稍后由 ControllerBuilder 类设置(“注入”)。
我正在使用的模板附带的CurrentUserService类尝试读取构造函数中的用户声明,因此我将代码移动到属性的 getter,它会在实际使用该属性时执行,然后所有声明和属性都是人口稠密。
我的新CurrentUserService如下所示:
using CleanREC0.Application.Common.Interfaces;
using Microsoft.AspNetCore.Http;
using System.Security.Claims;
namespace CleanREC0.WebUI.Services
{
public class CurrentUserService : ICurrentUserService
{
private IHttpContextAccessor _httpContextAccessor;
public CurrentUserService(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
public string UserId { get { return _httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.NameIdentifier); }}
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3030 次 |
最近记录: |