ASP.Net Core,Angular2和基于令牌的身份验证

时间:2017-01-04 21:39:47

标签: authentication asp.net-core jwt single-page-application

我正在编写一个使用ASP.NET核心作为后端/服务和Angular2作为前端的Web应用程序,并使用带有身份验证/授权的麻烦。

在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();
  [...]
}

但是我需要在Configure中设置哪些中间件?我需要app.UseIdentity()还是app.UseJwtBearerAuthentication(o)?在JwtBearer检查Tokens ??

之前,不会使用UseIdentity快捷方式进行身份验证
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");
}

关于身份验证,Cookie和令牌的更多好读物:
- http://andrewlock.net/exploring-the-cookieauthenticationmiddleware-in-asp-net-core/
- https://stormpath.com/blog/token-authentication-asp-net-core

1 个答案:

答案 0 :(得分:3)

MS提供了基于jwt令牌的基本身份验证库,您可以在此处查看如何使用它:

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());
        });

最后,在控制器中使用它,只需添加[授权(&#34; Bearer&#34;)]

   [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