一个 MVC Web 应用程序作为 API 和客户端



我有一个MVC Web应用程序,以及一个WPF客户端和Web API服务器。我非常想将 API 控制器拉入 MVC 应用程序,并且只有一个应用程序/api。我这样做的主要原因是为应用程序用户和 API 客户端提供一个登录过程。

我想做的是将SignInManager<ApplicationUser注入Token控制器并使用

var result = await _signInManager.PasswordSignInAsync(login.Username, login.Password, false, false);

使用与构建到 MVC 项目中相同的密码哈希器对用户名和密码进行身份验证。我不想复制任何这种类型的功能。我还希望,有了这个,实现一个提供 JWT 令牌的登录,让 WPF 应用程序访问事物的 API 端,以及一个标准的登录 cookie,用于授权正常的 MVC 应用程序请求。

我应该如何以最少的代码重复来做到这一点?

想法:使用一个MVC应用程序作为REST服务器。如果我获取 JWT 的Login操作也让我登录,例如使用_signInManager.PasswordSignInAsync,我还应该获取允许我在内部访问受保护操作的 cookie,并在外部使用它们与包含 JWT 的授权标头。

您可以考虑以下选项

选项 #1:将 MVC 应用中使用的逻辑移动到新的类库,然后 API 项目可以引用该类库。这将允许您遵循 SRP 并在 MVC 和 API 应用程序中使用相同的逻辑。如果要使 ASP.NET 标识相关功能在 MVC 和 API 应用中通用,请查看 ASP.NET 标识模型移动到类库并按照提供的步骤进行操作。

选项 #2:您可以将所有控制器和模型从 API 移动到 MVC 应用。然后,您可以将 API 控制器配置为使用 JWT 身份验证方案,并继续使用 MVC 应用程序的控制器的 cookie 身份验证方案。如果要遵循此方法,则需要配置身份验证中间件。例如,您的Startup类如下所示:

public void ConfigureServices(IServiceCollection services)
{
...
services.AddMvc();
services.AddAuthentication(o =>
{
o.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
o.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
o.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
}).AddCookie(options =>
{
options.AccessDeniedPath = new PathString("/Account/Login/");
options.LoginPath = new PathString("/Account/Login/");
}).AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options => {
options.TokenValidationParameters = new TokenValidationParameters 
{       
ValidateAudience = false,
ValidateIssuer = false,
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("<put_your_secret_here>")),
ValidateLifetime = true,
ClockSkew = TimeSpan.FromMinutes(5)            
};
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
...
app.UseAuthentication();
app.UseMvcWithDefaultRoute();
...
}    

然后,您可以定义可用于设置到 API 控制器的路由并授权它们的BaseApiController

例如
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[Route("api/[controller]")]
public abstract class BaseApiController {}

并使所有 API 控制器继承此基本控制器。您还可以使用更灵活的基于策略的授权。完成后,您将能够使用 MVC 应用控制器中的 cookie 和 API 控制器中的 JWT 令牌进行身份验证。

选项 #3:您可以让 API 和 MVC 应用程序单独运行,并使用 IdentityServer 实现 OAuth 协议。将其添加到 MVC 应用,因为它与 ASP.NET 标识很好地集成并对其进行配置,以便继续使用 MVC 应用的 cookie 身份验证方案。然后配置其中一个 OAuth 流,以设置 WPF 应用和 API 之间的授权。IdentityServer 有很好的文档记录,并在其 GitHub 中提供了不同流的示例。这种方法的优点是,即使您考虑添加更多必须使用相同的用户群的API,SPA或MVC应用程序,将来也不会遇到此类问题。此外,它还允许实现单点登录(SSO),因此如果您需要另一个MVC应用程序,可以轻松地将其集成到现有基础架构中。

最新更新