ASP.Net Core,Angular2和基于令牌的认证

我正在编写一个Web应用程序,使用ASP.NET核心作为后端/ Service和Angular2作为前端,并使用认证/授权来解决问题。

在ASP.NET核心中,我只有一个html页面和控制器,带有允许匿名访问的索引的HomeController([AllowAnonymous])。 这个单页面将angular2-app发送给客户端。

所有其他通信都使用ApiControllers(它在ASP.NET核心中只是普通的控制器,但是这些控制器上的操作期望并发送JSON数据。对于身份验证/授权,我想使用jwt令牌,用户,角色,索赔等存储在使用EF核心的IdentityDbContext中。

我发现的大多数教程都过时,不完整或涉及第三方OAuth解决方案。 我不在寻找OAuth,我只是想要一个带有用户名/密码的页面,并使用令牌保持登录状态,因为我使用所有的API来获取来回的数据。 我阅读了很多教程,尝试了一些有用的库,但仍然对如何设置中间件链以获得基于令牌的安全性感到困惑。 据我所知我需要添加服务的身份,因为我想使用IdentityDbContext:

public void ConfigureServices(IServiceCollection services)
{
  [...]
  services.AddIdentity<IdentityUserEntity, IdentityRoleEntity>()
    .AddEntityFrameworkStores<ApplicationDbContext, long>()
    .AddDefaultTokenProviders();
  [...]
}

但是,我需要在配置中设置哪些中间件? 我需要app.UseIdentity()还是会app.UseJwtBearerAuthentication(o)足够? JwtBearer在检查令牌之前得到一个镜头之前,不会使用Identity快捷方式进行验证?

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
  [...]
  app.UseIdentity();
  [...]
  app.UseJwtBearerAuthentication(jwtOptions);
  [...]
}

我问,因为客户端在我的TokenController中自动进行了身份验证,我对_signInManager.PasswordSignInAsync(...)执行了调用,即使我的客户端从未收到jwt。 因此不知何故,ASP.NET身份管理在登录后发现了一些其他方式来识别我的用户,这当然不应该发生。

// simplified controller
public class TokenController : Controller
{
  [HttpPost("[action]")]
  [AllowAnonymous]
  public async Task<JsonResult> Login([FromBody]LoginViewModel loginRequest)
  {
    var signin = await _signInManager.PasswordSignInAsync(loginRequest.Username, loginRequest.Passwort, true, true);
  }

  // this will work even though I don't handle any Tokens in the Client yet, so some other authentication mechanism is at work:
  [HttpGet("test")]
  [Authorize]
  public IActionResult Get()
  {
    return new JsonResult(from c in User.Claims select new { c.Type, c.Value });
  }

} 

那么如何实现基于令牌的认证,而不是其他?

[UPDATE]

我想我需要拦截Cookie身份验证事件,并拒绝主体以禁用Cookie身份验证(请参阅https://stackoverflow.com/a/38893778/7021):但由于某种原因,我的事件处理程序永远不会被调用。

  app.UseCookieAuthentication(new CookieAuthenticationOptions()
  {
    Events = new CookieAuthenticationEvents
    {
      OnValidatePrincipal = ValidateAsync
    }
  });

public static async Task ValidateAsync(CookieValidatePrincipalContext context)
{
  context.RejectPrincipal();
  await context.HttpContext.Authentication.SignOutAsync("BsCookie");
}

关于auth,Cookies和令牌的更多精彩内容:
- http://andrewlock.net/exploring-the-cookieauthenticationmiddleware-in-asp-net-core/
- https://stormpath.com/blog/token-authentication-asp-net-core


MS已经提供了基本的基于jwt令牌的认证lib,你可以在这里看到如何使用它:

https://code.msdn.microsoft.com/How-to-achieve-a-bearer-9448db57

在startup.cs中,首先配置Jwt Beare

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        app.UseJwtBearerAuthentication(new JwtBearerOptions()
          {
              TokenValidationParameters = new TokenValidationParameters()
            {
                IssuerSigningKey = TokenAuthOption.Key,
                ValidAudience = TokenAuthOption.Audience,
                ValidIssuer = TokenAuthOption.Issuer,
                // When receiving a token, check that we've signed it.
                ValidateIssuerSigningKey = true,
                // When receiving a token, check that it is still valid.
                ValidateLifetime = true,
                // This defines the maximum allowable clock skew - i.e. provides a tolerance on the token expiry time 
                // when validating the lifetime. As we're creating the tokens locally and validating them on the same 
                // machines which should have synchronised time, this can be set to zero. Where external tokens are
                // used, some leeway here could be useful.
                ClockSkew = TimeSpan.FromMinutes(0)
            }
        });

现在你可以添加到服务

    public void ConfigureServices(IServiceCollection services)
    {
         services.AddAuthorization(auth =>
          {
            auth.AddPolicy("Bearer", new AuthorizationPolicyBuilder()
                .AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme‌​)
                .RequireAuthenticatedUser().Build());
        });

最后,在控制器中使用它,只需添加[Authorize(“Bearer”)]

   [Route("api/[controller]")]
   public class ValuesController : Controller
   {
      [HttpGet("GetStaff")]
      [Authorize("Bearer")]
       public IActionResult GetStaff()
      {
          List<string> model = new List<string>();
          foreach (User user in UserStorage.Users ){
           model.Add(user.Username);
          }
          return Json(model);
      }
    }

查看全部细节:https://github.com/Longfld/ASPNETcoreAngularJWT

链接地址: http://www.djcxy.com/p/3817.html

上一篇: ASP.Net Core, Angular2 and token based authentication

下一篇: ASP.NET Core Web API Authentication