在.net核心web api中的何处存储JWT令牌?
我使用web api访问数据,我想对web api进行身份验证和授权。为此,我使用JWT令牌身份验证。但我不知道应该在哪里存储访问令牌 我想做什么 1) 登录后存储令牌 2) 如果用户希望访问web api的任何方法,请检查令牌对此用户是否有效,如果有效,则授予访问权限 我知道两种方法 1) 使用cookies 2) sql server数据库在.net核心web api中的何处存储JWT令牌?,api,authentication,jwt,Api,Authentication,Jwt,我使用web api访问数据,我想对web api进行身份验证和授权。为此,我使用JWT令牌身份验证。但我不知道应该在哪里存储访问令牌 我想做什么 1) 登录后存储令牌 2) 如果用户希望访问web api的任何方法,请检查令牌对此用户是否有效,如果有效,则授予访问权限 我知道两种方法 1) 使用cookies 2) sql server数据库 哪一种是存储上述代币的更好方法?我不熟悉将用户代币存储在后端应用程序上,我将快速检查这是如何工作的。但是,如果您使用dotnet core通过Cooki
哪一种是存储上述代币的更好方法?我不熟悉将用户代币存储在后端应用程序上,我将快速检查这是如何工作的。但是,如果您使用dotnet core通过Cookie或jwt进行身份验证,根据我的理解和经验,您无需存储任何东西 如果您正在使用cookie,那么您只需要配置中间件来验证cookie的有效性,如果cookie出现在用户/消费者的标题中,并且如果cookie不可用、已过期或无法解决,您只需拒绝请求,用户甚至不会点击任何受保护的控制器和操作。这里有一个非常简单的cookie方法(我还在开发中,还没有在生产中测试过,但现在使用JS客户端和Postman,它在本地运行得非常好) 显然,这将被放置或调用在启动的ConfigureServices方法中以注册身份验证 然后在启动时的配置方法中,连接身份验证
app.UseAuthentication();
以前
app.UseMvc()
或者,如果您只是想使用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();
}
}
}
[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();
}
我希望这些有帮助您能进一步解释一下您的用例吗。是否要在webapi上强制身份验证,以便调用者在调用控制器和操作之前需要进行身份验证,还是webapi正在调用另一个需要对您的调用进行身份验证的系统?如果您试图实现之前的选项,那么您不必担心,如果您已经完成了中间件的定制,除非您正在考虑剥离应用程序的多个实例,并且您需要在多个应用程序之间共享会话(但不确定为什么要使用会话)但是,如果您询问如何在成功身份验证后将令牌传递回调用方,则有两种选择。使用标准owin中间件来处理使用Bear的身份验证,然后您可以在响应中返回jwt(风险在于您的终端客户端保护令牌)或者将中间件配置为使用cookie身份验证,只返回带有标题集cookie的cookie,这样您的客户端就可以保存cookie,而不必担心任何其他应用程序能够访问其信息。为什么您认为您需要将jwt存储在任何位置?用于通过比较令牌验证用户是否有效这是一个解决方案,但这里的IUserDomain是什么…?没问题,不用担心,这些基本上只是服务编排,有助于执行某些操作,如到数据库验证用户凭据或调用内部身份验证系统。但您是否得到了一个基本信息,即您实际上不需要使用数据库来存储令牌
[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();
}