JWT令牌认证 - 正确行事

时间:2018-06-01 22:29:59

标签: asp.net-mvc authentication asp.net-web-api cookies jwt

我的项目结构概述:

我有2个项目。

  1. Asp.net核心Web Api
  2. Asp.net核心Web MVC
  3. 在Web Api项目中

    • 我没有使用Asp.net核心身份进行登录,而是使用我自己的登录机制。
    • LoginAction方法将对数据库中的用户进行身份验证并生成JWT令牌。
    • 我能够生成JWT令牌,直到此时人生还很顺利。

    生成令牌

            [AllowAnonymous]
            [Route("requesttoken")]
            [HttpPost]
            public async Task<IActionResult> RequestToken([FromBody] TokenRequest request)
            {        
                var result = await IsValidUser(request);
                if(result)
                {
                    var claims = new[]
                    {
                        new Claim(ClaimTypes.Name, request.Email)
                    };
    
                    var key = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(_myAppSettings.SecurityKey));
                    var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
    
                    var token = new JwtSecurityToken(
                        issuer: _myAppSettings.WebsiteName.ToLower(),
                        audience: _myAppSettings.WebsiteName.ToLower(),
                        claims: claims,
                        notBefore: Utilities.GetEST_DateTimeNow(),
                        expires: Utilities.GetEST_DateTimeNow().AddMinutes(5),                    
                        signingCredentials: creds);
    
                    return Ok(new
                    {
                        token = new JwtSecurityTokenHandler().WriteToken(token)
                    });
                }
                else
                {
                    return Unauthorized();
                }
            }
    

    内部启动课程

    // This method gets called by the runtime. Use this method to add services to the container.
            public void ConfigureServices(IServiceCollection services)
            {
                services.Configure<MyAppSettings>(Configuration.GetSection("MyAppSettings"));
    
                #region Validate JWT Token
                ConfigureJwtAuthService(services, Configuration);
                #endregion
    
                services.AddMvc();
            }
    
            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IHostingEnvironment env)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
    
                app.UseAuthentication();
    
                app.UseMvc();
            }
    

    JWT验证部分(作为部分启动类)

    public void ConfigureJwtAuthService(IServiceCollection services, IConfiguration configuration)
            {
                var symmetricKeyAsBase64 = configuration["MyAppSettings:SecurityKey"];
                var keyByteArray = Encoding.ASCII.GetBytes(symmetricKeyAsBase64);
                var signingKey = new SymmetricSecurityKey(keyByteArray);
    
                var tokenValidationParameters = new TokenValidationParameters
                {
                    // The signing key must match!
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = signingKey,
    
                    // Validate the JWT Issuer (iss) claim
                    ValidateIssuer = true,
                    ValidIssuer = Configuration["MyAppSettings:WebsiteName"].ToLower(),
    
                    // Validate the JWT Audience (aud) claim
                    ValidateAudience = true,
                    ValidAudience = Configuration["MyAppSettings:WebsiteName"].ToLower(),
    
                    // Validate the token expiry
                    ValidateLifetime = true,
    
                    ClockSkew = TimeSpan.Zero
                };
    
                services.AddAuthentication(
                options =>
                {
                    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                })
                .AddJwtBearer(o => o.TokenValidationParameters = tokenValidationParameters);
            }
    

    LoginAction方法的示例响应。 { "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkrDtGhuIETDs8OoIiwiYWRtaW4iOnRydWV9.469tBeJmYLERjlKi9u6gylb-2NsjHLC_6kZNdtoOGsA" }

    在Web MVC项目中

    • 我正在使用Web Api并传递登录参数,并且能够获得JWT令牌响应。
    • 我在Cookie [手动 - _httpContextAccessor.HttpContext.Response.Cookies.Append(key, jwtTokenValue, option);]
    • 中存储JWT令牌响应
    • 基于JWT令牌响应接收,我试图从该JWT令牌中提取声明,以便我能够在网络上创建用户和登录用户的有效身份。

    我正在努力实现以下目标:

                {
                    var claims = new List<Claim>
                    {
                        new Claim(ClaimTypes.Name, model.Email)
                    };
                    var userIdentity = new ClaimsIdentity(claims, "login");
                    ClaimsPrincipal principal = new ClaimsPrincipal(userIdentity);
                    await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal);
                    return RedirectToLocal(returnUrl);
                }
    

    问题

    1. 我是否正确将JWT令牌存储在cookie中。我手动存储cookie的方法是正确的还是有更好的方法?
    2. 如何从Web项目中获取JWT的声明,以便我能够使用cookie唱出用户?
    3. 想要以正确的方式行事,我们将非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

以下似乎帮助了我:http://blogs.quovantis.com/json-web-token-jwt-with-web-api/不确定这是否是正确的做法。

/// Using the same key used for signing token, user payload is generated back
        public JwtSecurityToken GenerateUserClaimFromJWT(string authToken)
        {

            var tokenValidationParameters = new TokenValidationParameters()
            {
                ValidAudiences = new string[]
                      {
                    "http://www.example.com",
                      },

                ValidIssuers = new string[]
                  {
                      "self",
                  },
                IssuerSigningKey = signingKey
            };
            var tokenHandler = new JwtSecurityTokenHandler();

            SecurityToken validatedToken;

            try {

              tokenHandler.ValidateToken(authToken,tokenValidationParameters, out validatedToken);
            }
            catch (Exception)
            {
                return null;

            }

            return validatedToken as JwtSecurityToken;

        }