c# - 如何向已经使用 Identity 的 MVC 控制器添加 API 身份验证和授权?
问题描述
语境
我有一个带有多个控制器的 ASP.NET Core MVC 应用程序(仅返回视图)。该应用已使用 ASP.NET Core Identity 进行身份验证和授权。但是,有几个地方我需要使用 HTTP 客户端直接调用控制器操作端点作为 API。这似乎需要 Identity 似乎不支持开箱即用的 API 身份验证。
问题
我需要使用组件标签助手(渲染模式为)从嵌入到我的 MVC 视图中的 Razor 组件调用这些控制器操作ServerPrerendered
。
现在,我可以直接从我的 Razor 组件访问我的数据库,方法是将数据库服务注入到我的组件中,就像我为其他 Razor 组件所做的那样。但是,我不能用这个 Razor 组件来做到这一点,因为它需要访问UserManager
Identity 服务并且根据文档:
SignInManager<TUser>
并且UserManager<TUser>
在 Razor 组件中不受支持。Blazor 服务器应用使用 ASP.NET Core 标识。
因此,似乎我可能不得不通过注入从我的 Razor 组件调用控制器操作IHttpClientFactory
。但是,到目前为止,在我的整个应用程序中,我只需要为两个操作调用控制器操作:
- 用于创建用户
- 用于编辑用户
您可能会问为什么我需要 Razor 组件来创建用户帐户。创建帐户是一个相当复杂的步骤(多个步骤),涉及客户端交互,例如将项目动态添加到列表中。Razor 组件让我变得如此简单。.cshtml
如果我在视图中执行此操作,我将不得不使用 JavaScript/jQuery 。
目标
我不认为仅仅为了帮助我完成这两个操作而创建一个完整的 API 项目是值得的(尽管我不介意这样做)。我可以将这些操作添加到我现有的帐户控制器或在同一个项目中创建一个新的 API 控制器。尽管如此,我仍然必须保护这些端点。
主要问题
如何向这两个控制器操作(创建用户和编辑用户)添加 API 身份验证和授权,而不干扰现有的 ASP.NET Core 身份设置正在做什么?
我仍然希望我的应用程序中的其余控制器具有相同的身份验证/授权,但这些Create
和Edit
用户操作的 API 身份验证/授权。
或者由于我的 Razor 组件嵌入在 MVC 视图中,有没有办法通过我的组件调用控制器操作,就像 MVC 视图通过发送带有请求的 cookie 一样?
无论哪种方式,我的目标是保护两个控制器操作端点。
代码
这是身份当前配置的方式Startup.cs
:
services.AddDefaultIdentity<AppUser>()
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<AppDbContext>();
这是我的Create
控制器操作的简化版本:
[Authorize(Roles = "Administrator")]
public async Task<IActionResult> Create(UserViewModel model)
{
if (ModelState.IsValid)
{
AppUser user = model.ToAppUser(); // Method on view model does the mapping
user.Id = Guid.NewGuid().ToString();
IdentityResult createUserResult = await _userManager.CreateAsync(user, model.Password);
if (createUserResult.Succeeded)
{
await userManager.AddToRoleAsync(user, role.Name);
return Ok();
}
foreach(var error in createUserResult.Errors)
{
ModelState.AddModelError("", error.Description);
}
}
}
这就是我从 Razor 组件调用它的方式:
CreateUser.razor
:
@inject IHttpClientFactory HttpClientFactory
<EditForm Model="_model" OnValidSubmit="HandleValidSubmit">
...
</EditForm>
@code {
private UserViewModel _model = new();
public async Task HandleValidSubmit()
{
var modelAsJson = new StringContent(
JsonSerializer.Serialize(_model),
Encoding.UTF8,
"application/json");
using var httpResponse =
await _httpClient.PostAsync("/api/Accounts/Create", modelAsJson);
//...
}
}
使用以下方法将组件嵌入到 MVC 视图中<component>
:
Create.cshtml
...
<component type="typeof(CreateUser)" render-mode="ServerPrerendered" />
更新
经过一番研究,我发现 JWT 是最常用的 API 身份验证方式。根据此处的说明,它是这样添加的Startup.cs
:
services.AddAuthentication( auth =>
{
auth.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
auth.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options => {..})
在这里,当默认身份验证方案设置为 JWT 时,这会覆盖我的默认身份设置吗?如何同时使用这两种方案?
解决方案
有一种方法可以在 asp.net 核心中支持多种身份验证方案。
它看起来像这样:
启动类:
public void ConfigureServices(IServiceCollection services)
{
serviced.AddDefaultIdentity<AppUser>()
.AddRoles<IdentityUser>()
.AddEntityFrameworkStores<AppDbContext>();
services.AddAuthentication()
.AddCookie(options => {
options.LoginPath = "/Account/Unathorized/"
options.AddAccessDeniedPath = "/Account/Forbidden"
});
}
控制器:
[Authorize(AuthenticationSchemes = YourCustomeScheme)]
public class AuthController: controller
您可以根据需要添加和使用任意数量的方案。
推荐阅读
- php - 如何在一对多表原则 2.0 中添加评论
- extjs - 步进进度条 ExtJs
- r - 返回具有给定 RGB/HEX 值的像素坐标
- regex - 将 preg_replace 与不同的变量替换一起使用
- python - 从 numpy 数组中获取信息
- c++ - 虚拟表的大小异常
- swift - 从详细信息视图导航到列表视图需要双击
- javascript - 如何将值归因于jquery点击功能
- php - Microsoft Dynamics crm api-在账户下创建联系人
- angular - 找不到模块导入 { async, TestBed } from '@angular/core/testing'; 从“离子角”导入 { IonicModule };