ASP.Net Core,Angular2和基于令牌的身份验证 [英] ASP.Net Core, Angular2 and token based authentication

查看:73
本文介绍了ASP.Net Core,Angular2和基于令牌的身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm writing a web application using ASP.NET core for the backend / Service and Angular2 as frontend and have Troubles with authentication / authorization.

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

In ASP.NET core I got just one html page&controller, HomeController with Index which allows anonymous Access ([AllowAnonymous]). This single page delivers the angular2-app to the Client.

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

All other communication is using ApiControllers (which in ASP.NET core are just normal Controllers, but the Actions on these Controllers expect and send JSON data. For authentication/authorization I want to use jwt tokens. Users, Roles, Claims etc. are stored in an IdentityDbContext using EF core.

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

Most tutorials I found are outdated, incomplete or refer to 3rd Party OAuth-solutions. I'm not looking for OAuth, I just want a page with username/Passwort and use Tokens to stay logged in since I'm using all API's to get data to and fro the backend. I read lots of tutorials, tried a few helpful libs, but still am confused about how to set up the Middleware chain for token-based security. As far as I understand I Need to add the Services for identity since I want to use IdentityDbContext:

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

但是我需要在Configure中设置什么中间件?我需要app.UseIdentity()还是app.UseJwtBearerAuthentication(o)足够?在JwtBearer尝试检查令牌之前,UseIdentity不会捷径认证吗?

But what Middleware do I Need to set up in Configure? Do I Need app.UseIdentity() or would app.UseJwtBearerAuthentication(o) enough? Wouldn't UseIdentity shortcut the authentication before the JwtBearer gets a shot at checking for Tokens??

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

我问,因为在我的TokenController中我自动调用了_signInManager.PasswordSignInAsync(...)之后,即使我的客户端从未收到jwt,也对客户端进行了自动验证.因此,以某种方式,ASP.NET身份管理在登录后找到了其他方法来识别我的用户,这当然不应该发生.

I ask because the Client automagically was authenticated after in my TokenController I performed a call to _signInManager.PasswordSignInAsync(...), even though my client did never receive the jwt. So somehow ASP.NET identity Management found some other way to identify my user after signing in, which of course should not happen.

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

} 

那我该如何实现基于令牌的身份验证而没有其他?

So how do I implement token based authentication and nothing else?

[更新]

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

I'd guess I Need to intercept the Cookie authentication event and reject the principal to disable Cookie auth (see https://stackoverflow.com/a/38893778/7021): But for some reason my event handler never gets called.

  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,Cookie和令牌的更多佳读:
- http://andrewlock.net/exploring-the-cookieauthenticationmiddleware- in-asp-net-core/
- https://stormpath.com/blog/token-authentication-asp-net -核心

More good reads about auth, Cookies and token:
- http://andrewlock.net/exploring-the-cookieauthenticationmiddleware-in-asp-net-core/
- https://stormpath.com/blog/token-authentication-asp-net-core

推荐答案

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

MS has provided basic jwt token based authentication lib, you can see how to use it here:

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

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

In startup.cs, firstly config 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")]

Finally, use it in controller, simply add [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

Check full details here: https://github.com/Longfld/ASPNETcoreAngularJWT

这篇关于ASP.Net Core,Angular2和基于令牌的身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆