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

时间:2018-03-13 10:38:36

标签: c# security asp.net-core asp.net-core-mvc asp.net-identity

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

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

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

使用与构建到MVC项目中相同的密码hasher来验证用户名和密码。我不想复制任何类型的功能。我也希望通过这种方式实现一个登录,为WPF应用程序提供一个JWT令牌,以访问API方面的内容,以及一个标准的登录cookie,以便正常的MVC应用程序请求被授权。

如何以最少的代码重复进行此操作?

IDEA: 使用一个MVC应用程序作为REST服务器。如果获得JWT的Login行为也会让我签名,例如:使用_signInManager.PasswordSignInAsync,我还应该获取允许我在内部访问受保护操作的cookie,并在外部使用包含JWT的授权头。

1 个答案:

答案 0 :(得分:12)

您可以考虑以下选项

选项#1 :将MVC应用程序中使用的逻辑移动到新的类库,然后可以通过API项目引用它。这将允许您遵循SRP并在MVC和API应用程序中使用相同的逻辑。如果您想使ASP.NET身份相关的功能在MVC和API应用程序中很常见,请查看Moving ASP.NET Identity Model to Class Library并按照提供的步骤进行操作。

选项#2:您可以将所有控制器和模型从API移动到MVC应用程序。您可以配置然后API控制器使用JWT身份验证方案并继续使用cookie身份验证方案fr MVC apps的控制器。如果要使用此方法,则需要配置身份验证中间件。例如,您的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();
    ...
}    

然后你可以定义BaseApiController,它可以用来设置到API控制器的路由并使用例如它来授权它们。

[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已有详细记录,可为不同的流in their GitHub提供样本。这种方法的优点是,即使您考虑添加更多必须使用相同用户群的API,SPA或MVC应用程序,您将来也不会遇到此类问题。此外,它还允许实现单点登录(SSO),因此如果您需要其他MVC应用程序,则可以轻松将其集成到现有基础架构中。