我正在使用Web api来访问数据,并且想对Web api进行身份验证和授权。为此,我正在使用JWT令牌身份验证。但是我不知道我应该在哪里存储访问令牌?
我想做什么?
1)登录后存储令牌
2)如果用户要访问任何Web api方法,请检查令牌对该用户有效,如果有效,则授予访问权限。
我知道两种方式
1)使用cookie
2)sql服务器数据库
哪种是从上方存储令牌的更好方法?
答案 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()