在.net核心Web API中将JWT令牌存储在哪里?

时间:2018-11-24 07:00:25

标签: api authentication jwt

我正在使用Web api来访问数据,并且想对Web api进行身份验证和授权。为此,我正在使用JWT令牌身份验证。但是我不知道我应该在哪里存储访问令牌?

我想做什么?

1)登录后存储令牌

2)如果用户要访问任何Web api方法,请检查令牌对该用户有效,如果有效,则授予访问权限。

我知道两种方式

1)使用cookie

2)sql服务器数据库

哪种是从上方存储令牌的更好方法?

2 个答案:

答案 0 :(得分:1)

或者,如果您只是想使用JWT进行身份验证,则实现会稍有不同

        services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        }).AddJwtBearer(options =>
        {
            options.Events = new JwtBearerEvents
            {
                OnTokenValidated = context =>
                {

                    var user = context.Principal.Identity.Name;
                  //Grab the http context user and validate the things you need to
                   //if you are not satisfied with the validation fail the request using the below commented code
                   //context.Fail("Unauthorized");

                     //otherwise succeed the request
                    return Task.CompletedTask;
                }
            };
            options.RequireHttpsMetadata = false;
            options.SaveToken = true;
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey("MyVeryStrongKeyHiddenFromAnyone"),
                ValidateIssuer = false,
                ValidateAudience = false

            };
        });

在使用MVC之前仍要应用使用身份验证。

[请注意,这些是非常简化的示例,您可能需要进一步加强安全性并实施最佳实践,例如使用强键,可能从环境中加载配置等]

然后执行实际的身份验证操作,例如在AuthenticationController中可能是

[Route("api/[controller]")]
    [Authorize]
    public class AuthenticationController : Controller
    {


        [HttpPost("authenticate")]
        [AllowAnonymous]
        public async Task<IActionResult> AuthenticateAsync([FromBody]LoginRequest loginRequest)
        {
//LoginRequest may have any number of fields expected .i.e. username and password

           //validate user credentials and if they fail return
                //return Unauthorized();

            var claimsIdentity = new ClaimsIdentity(new Claim[]
               {
                //add relevant user claims if any
               }, "Cookies");

            var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
            await Request.HttpContext.SignInAsync("Cookies", claimsPrincipal);
            return Ok();
        }
    }
}

在这种情况下,我正在使用Cookie,所以我将返回带有Set Cookie的HTTP结果。如果我使用的是JWT,我会返回类似

的内容
[HttpPost("authenticate")]
    public IActionResult Authenticate([FromBody]LoginRequest loginRequest)
    {

           //validate user credentials and if they validation failed return a similar response to below
                //return NotFound();

        var tokenHandler = new JwtSecurityTokenHandler();
        var key = Encoding.ASCII.GetBytes("MySecurelyInjectedAsymKey");
        var tokenDescriptor = new SecurityTokenDescriptor
        {
            Subject = new ClaimsIdentity(new Claim[]
            {
//add my users claims etc
            }),
            Expires = DateTime.UtcNow.AddDays(1),//configure your token lifespan and needed
            SigningCredentials = new SigningCredentials(new SymmetricSecurityKey("MyVerySecureSecreteKey"), SecurityAlgorithms.HmacSha256Signature),
            Issuer = "YourOrganizationOrUniqueKey",
            IssuedAt = DateTime.UtcNow
        };

        var token = tokenHandler.CreateToken(tokenDescriptor);
        var tokenString = tokenHandler.WriteToken(token);
        var cookieOptions = new CookieOptions();
        cookieOptions.Expires = DateTimeOffset.UtcNow.AddHours(4);//you can set this to a suitable timeframe for your situation 
        cookieOptions.Domain = Request.Host.Value;
        cookieOptions.Path = "/";
        Response.Cookies.Append("jwt", tokenString, cookieOptions);
        return Ok();

    }

希望这些对您有帮助

答案 1 :(得分:0)

我不熟悉将用户令牌存储在后端应用程序中的情况,我将快速检查其工作原理,但是根据我的理解和经验,如果您使用dotnet core来通过cookie或jwt进行身份验证,不需要在你身边存储任何东西。

如果您使用的是cookie,则只需配置中间件以验证cookie的有效性(如果它出现在用户/使用者的标头中,并且如果不可用或已过期或无法解析,则只需拒绝)该请求,该用户甚至不会点击您任何受保护的控制器和操作。这是使用cookie的一种非常简化的方法。(我仍在使用它进行开发,并且还没有在生产中进行测试,但是现在使用JS客户端和Postman在本地工作得很好)

    services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
   .AddCookie(options =>
   {
       options.Cookie.Name = "yourCookieName";
       options.Cookie.SameSite = SameSiteMode.None;//its recommended but you can set it to any of the other 3 depending on your reqirements
       options.Events = new Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationEvents
       {
           OnRedirectToLogin = redirectContext =>//this will be called if an unauthorized connection comes and you can do something similar to this or more
           {
               redirectContext.HttpContext.Response.StatusCode = 401;
               return Task.CompletedTask;
           },
           OnValidatePrincipal = context => //if a call comes with a valid cookie, you can use this to do validations. in there you have access to the request and http context so you should have enough to work with
           {
               var userPrincipal = context.Principal;//I'm not doing anything with this right now but I could for instance validate if the user has the right privileges like claims etc
               return Task.CompletedTask;
           }
       };
   }); 

很明显,这将被放置或在启动时的ConfigureServices方法中调用以注册身份验证

,然后在启动的Configure方法中,连接

之类的Authentication。
app.UseAuthentication();

之前

app.UseMvc()