好的,首先让我说我对 ASP.NET Core 和一般的 Web 开发还比较陌生。虽然我过去做过一些小项目。
我正处于迷失方向,无法弄清楚我的问题是什么。我希望你至少能指出我正确的方向。
TLDR:使用 WebApi 对 Blazor 应用进行身份验证和授权
我想创建一个由 ASP.Core 5 应用程序托管的 Blazor WebAssembly 应用程序。业务逻辑将由另一个 WebApi 执行。
所以我有 3 个相关的项目:
WebHost 只是要托管在 docker 容器中,该容器将在反向代理之后运行。所以我所做的一切都是在本地的 http 上运行。
Blazor 通过 WebApi ApiController (REST Api) 与后端通信。
前端有一些区域需要用户身份验证和授权。 WebApi 旨在解决这个问题。
我的问题就在这里。
我已使用自定义的 IdentityUser
、IdentityRole
、IUserStore
等将 IdentityService 添加到我的 WebApi。
当我使用 Swagger 测试我的 Api 时,注册、登录、更改密码等工作正常。
我的问题:WebApi 不记得登录。这意味着我可以登录并且我的 SignInManager
告诉我一切都很好,但是当我下次调用端点时控制器将不知道有关用户的任何信息。
当我成功调用登录端点时,浏览器中存储了一个 cookie。当我检查后端上的 HttpContext
时,我可以看到 cookie。
我尽量保持片段简短并删除不相关的部分。
启动配置方法
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseSwagger();
app.UseSwaggerUI(...);
app.UseEndpoints(x => x.MapControllers());
启动ConfigureServices方法
services.AddControllers();
services.AddSwaggerGen(...);
services.AddScoped<IUserManager, AppUserManager>();
services.AddScoped<ISignInManager, AppSignInManager>();
services.AddTransient<IUserStore<AppUser>, AppUserStore>();
services.AddTransient<IRoleStore<AppRole>, AppRoleStore>();
services.AddIdentity<AppUser, AppRole>()
.AddDefaultTokenProviders();
services.Configure<IdentityOptions>(...);
services.AddHttpContextAccessor();
services.AddAuthentication();
services.AddAuthorization();
身份验证控制器端点
[HttpPost(nameof(Login))]
public async Task<IActionResult> Login([FromBody] LoginUserCommand command)
{
// I've abstracted my logic into a Mediator Command
// but simplified this is just
// SignInManager.PasswordSignInAsync(user, pass, rememberMe)
// ClaimsFactory.CreateAsync(user)
var result = await Mediator.Send(command);
if (result.Succeeded)
{
// I've tried the following 2 methods to store the ClaimsPrincipal with no success
await HttpContext.SignInAsync(result.Data);
var signInResult = SignIn(result.Data); // positive result
return Ok(...);
}
return BadRequest(...);
}
swagger 发出的 POST 请求
curl -X POST "http://localhost:4000/_api/v1/Auth/Login"
-H "accept: */*"
-H "Content-Type: application/json"
-d "{\"password\":\"P4$$w0rd\",\"rememberMe\":true,\"username\":\"admin\"}"
存储在浏览器中的 Cookie
Name: Identity.External
Content: CfDJ8EGl21FYRChCvuGjMRYlEqvNaCBZMxNrNE8D [...]
Domain: localhost
Path: /
Created: 5 minutes ago
Expires: When the browsing session ends
答案 0 :(得分:0)
尝试在使用身份验证服务时添加 cookie 方案:
services.AddAuthentication(options =>
{
options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
}).AddCookie(CookieAuthenticationDefaults.AuthenticationScheme);
然后,当您登录时使用相同的方案:
var claimsIdentity = new ClaimsIdentity(
claims, CookieAuthenticationDefaults.AuthenticationScheme);
var authProperties = new AuthenticationProperties
{
IsPersistent = true,
};
await httpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
authProperties);