[英]JWT Authorization using HttpOnly cookie
I am making a web application using ASP.NET Core using CookieAuthentication
as my MVC authentication and JWT for Web-APIs.我正在使用 ASP.NET 核心制作 web 应用程序,使用
CookieAuthentication
作为我的 MVC 身份验证,JWT 用于 Web-API。
I have configured the cookie authentication and created the JWT token successfully.我已经配置了 cookie 身份验证并成功创建了 JWT 令牌。 However I have trouble authorizing my API methods that contain the
[Authorization(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
attribute.但是,我无法授权包含
[Authorization(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
属性的 API 方法。
Startup.cs启动.cs
services
.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.Cookie.Name = "CookieAuthentication";
options.Cookie.HttpOnly = true;
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
options.ExpireTimeSpan = TimeSpan.FromDays(14);
options.LoginPath = "/Account/Login";
options.LogoutPath = "/Account/Logout";
options.AccessDeniedPath = "/Account/Unauthorized";
});
services
.AddAuthentication()
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = Configuration["Jwt:JwtIssuer"],
ValidAudience = Configuration["Jwt:JwtAudience"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:JwtSecretKey"]))
};
});
AccountController.cs AccountController.cs
[HttpPost]
[Route("Login")]
[AllowAnonymous]
public async Task<IActionResult> Login([FromForm]LoginViewModel model)
{
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
if (model.Username == "test" && model.Password == "test")
{
var name = "Name";
var role = "Admin";
var email = "test123@gmail.com";
var claims = new List<Claim>()
{
new Claim(ClaimTypes.Name, name),
new Claim(ClaimTypes.Email, email),
new Claim(ClaimTypes.Role, role)
};
var credientials = new SigningCredentials(
new SymmetricSecurityKey(
Encoding.UTF8.GetBytes(_config["Jwt:JwtSecretKey"])),
SecurityAlgorithms.HmacSha256);
var securityToken = new JwtSecurityToken(
issuer: _config["Jwt:JwtIssuer"],
audience: _config["Jwt:JwtIssuer"],
claims: claims,
expires: DateTime.Now.AddMinutes(1),
signingCredentials: credientials
);
HttpContext.Response.Cookies.Append(
"JwtCookie",
"Bearer " + new JwtSecurityTokenHandler().WriteToken(securityToken),
new CookieOptions
{
Expires = DateTime.Now.AddMinutes(1),
HttpOnly = true,
Secure = true,
SameSite = SameSiteMode.Strict
});
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
var authenticationProperties = new AuthenticationProperties()
{
ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(1),
IsPersistent = true
};
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
authenticationProperties);
#endregion
return Redirect($"{role}/Index");
Private.cshtml私有.cshtml
@{
ViewData["Title"] = "Private";
}
<h2>Private Area</h2>
<input type="button" onclick="addUser()" value="Login" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script>
function addUser()
{
$.ajax
({
type: 'POST',
url: '/api/Test/AddUser'
}).done(function (data)
{
console.log("done");
}).fail(function (data, textStatus, xhr)
{
console.log("fail");
})
}
</script>
/api/Test/AddUser method /api/Test/AddUser 方法
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[HttpPost]
[Route("AddUser")]
public IActionResult AddUser()
{
var u = new User
{
SamAccountName = "Test",
Role = ""
};
_context.Add(u);
try
{
_context.SaveChanges();
}
catch (Exception e)
{
return BadRequest($"Cannot save: {e}");
}
return Ok();
}
The question I have is:我的问题是:
I am getting 401 error when I try to call the api/Test/AddUser
method.当我尝试调用
api/Test/AddUser
方法时出现 401 错误。 Is there a way I can send the cookie containing the JWT token through the authorization header automatically, similar to how CookieAuthentication
does it?有没有一种方法可以通过授权 header 自动发送包含 JWT 令牌的 cookie,类似于
CookieAuthentication
的方式? I know this is because of my not having an Authorization header.我知道这是因为我没有授权 header。 However because I stored my JWT token inside the HttpOnly cookie, I cannot find a way to pass the token into the authorization header.
但是,因为我将 JWT 令牌存储在 HttpOnly cookie 中,所以我找不到将令牌传递到授权 header 的方法。 I could add Authorization { "Bearer " + token }.
我可以添加授权{“承载”+令牌}。 I would have to use sessionStorage or use a normal cookie but that would pop up some security concerns.
我将不得不使用 sessionStorage 或使用普通的 cookie,但这会引发一些安全问题。 I have seen many tutorials but have never seen how the javascript passes its authorization header, most show passing through authorization header in Postman.
我看过很多教程,但从未见过 javascript 如何通过授权 header,大多数显示通过授权 header 在 Z34C061E1976CEDF27.
If the above could be done, is there a way the expiration date could be synced up with the CookieAuthentication
cookie?如果上述可以完成,是否有办法将到期日期与
CookieAuthentication
cookie 同步? Since a JWT token expiration date cannot be extended like cookie, how would I ensure that the user is able to access the APIs and MVC if they are using two different types of authentication?由于 JWT 令牌到期日期不能像 cookie 一样延长,如果用户使用两种不同类型的身份验证,我将如何确保他们能够访问 API 和 MVC?
The project only uses HTTPS and I implemented anti forgery tokens inside the forms I submit.该项目仅使用 HTTPS 并且我在我提交的 forms 中实现了防伪令牌。 Is there any attacks I should protect against?
有什么我应该防范的攻击吗?
A little bit late, but I think you'll find the answer to your problem with this answer有点晚了,但我想你会用这个答案找到你的问题的答案
How can I validate a JWT passed via cookies? 如何验证通过 cookies 传递的 JWT?
The basic idea is to create a middleware to intercept the request, check if it contains the token in the cookie, extract the token, and configure the authorization header of the request.基本思路是创建一个中间件拦截请求,检查cookie中是否包含token,提取token,配置请求的授权header。 After this, your request should have the authorization header with the token, and the Authorize data annotation should kick in
在此之后,您的请求应该具有带有令牌的授权 header,并且授权数据注释应该启动
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.