Asp.Net Core Identity 使用 JWT 中的哪些信息来授权令牌有效?
What information in a JWT does Asp.Net Core Identity use to authorise a token as valid?
我一直在玩 Asp.Net Core 和 JWT 以了解 JWT。我的流程之一总是通过删除和更改信息来制作内容 'unwork'。当我这样做时,我注意到我的项目会授权一个令牌,只要它只包含以下有效负载(有效负载已由 api 生成并且我删除了所有内容,但以下部分除外):
{
"exp": 1633534580,
"iss": "http://localhost:59921",
"aud": "http://localhost:4200"
}
这似乎是一个安全问题,因为 'iss' 和 'aud' 会随着时间的推移保持不变,只有 'exp' 必须是正确的猜测,这很难,获得有效的令牌。因此,我想知道 Identity 如何处理 JWT 以确定它是否有效,以及我作为开发人员可以做什么或实施什么来提高使用 JWT 的安全性以允许人们访问我的 api's端点?
生成令牌的代码是这样的:
public async Task<IActionResult> Login([FromBody] LoginModel model)
{
var user = await userManager.FindByNameAsync(model.Username);
if (user != null && await userManager.CheckPasswordAsync(user, model.Password))
{
var userRoles = await userManager.GetRolesAsync(user);
var authClaims = new List<Claim>
{
new Claim(ClaimTypes.Name, user.UserName),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
};
foreach (var userRole in userRoles)
{
authClaims.Add(new Claim(ClaimTypes.Role, userRole));
}
var authSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JWT:Secret"]));
var token = new JwtSecurityToken(
issuer: _configuration["JWT:ValidIssuer"],
audience: _configuration["JWT:ValidAudience"],
expires: DateTime.Now.AddHours(3),
claims: authClaims,
signingCredentials: new SigningCredentials(authSigningKey, SecurityAlgorithms.HmacSha256)
);
return Ok(new
{
token = new JwtSecurityTokenHandler().WriteToken(token),
expiration = token.ValidTo
});
}
return Unauthorized();
}
我的启动文件包含这个,关于身份验证。
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.SaveToken = true;
options.RequireHttpsMetadata = false;
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true,
ValidateAudience = true,
ValidAudience = Configuration["JWT:ValidAudience"],
ValidIssuer = Configuration["JWT:ValidIssuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JWT:Secret"]))
};
});
--- 编辑 ---
我想对于生成令牌的人来说,他们还需要知道签名中的密钥,这确实增加了一些额外的安全性。
JWT 是独立的、按价值计算的令牌,一旦发布并交付给接收者就很难撤销它们。因此,您应该为您的令牌使用尽可能短的到期时间 - 最多几分钟或几小时。您应该避免以天或月为单位给出您的令牌到期时间。
请记住,包含到期时间的 exp 声明并不是唯一可用于验证的基于时间的声明。 nbf 声明包含“不早于”时间。如果当前时间早于 nbf 声明中的时间,则应拒绝令牌。另一个基于时间的声明是 iat - issued at。您可以使用此声明拒绝您认为太旧而无法与您的资源服务器一起使用的令牌。
在处理基于时间的声明时请记住,不同机器之间的服务器时间可能略有不同。在检查基于时间的值时,您应该考虑允许时钟偏差。这应该是几秒的值,我们不建议为此目的使用超过 30 秒,因为这更像是服务器问题,而不是常见的时钟偏差。
关于安全性,jWT 安全性在很大程度上取决于令牌的实现和使用方式。仅仅因为 JWT 包含加密签名,并不自动意味着它是安全的,或者您应该盲目地信任令牌。
您可以关注密码学的安全标准和安全级别:
JSON Web Token Best Current Practices and RFC 7518 JSON Web Algorithms (JWA)
我一直在玩 Asp.Net Core 和 JWT 以了解 JWT。我的流程之一总是通过删除和更改信息来制作内容 'unwork'。当我这样做时,我注意到我的项目会授权一个令牌,只要它只包含以下有效负载(有效负载已由 api 生成并且我删除了所有内容,但以下部分除外):
{
"exp": 1633534580,
"iss": "http://localhost:59921",
"aud": "http://localhost:4200"
}
这似乎是一个安全问题,因为 'iss' 和 'aud' 会随着时间的推移保持不变,只有 'exp' 必须是正确的猜测,这很难,获得有效的令牌。因此,我想知道 Identity 如何处理 JWT 以确定它是否有效,以及我作为开发人员可以做什么或实施什么来提高使用 JWT 的安全性以允许人们访问我的 api's端点?
生成令牌的代码是这样的:
public async Task<IActionResult> Login([FromBody] LoginModel model)
{
var user = await userManager.FindByNameAsync(model.Username);
if (user != null && await userManager.CheckPasswordAsync(user, model.Password))
{
var userRoles = await userManager.GetRolesAsync(user);
var authClaims = new List<Claim>
{
new Claim(ClaimTypes.Name, user.UserName),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
};
foreach (var userRole in userRoles)
{
authClaims.Add(new Claim(ClaimTypes.Role, userRole));
}
var authSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JWT:Secret"]));
var token = new JwtSecurityToken(
issuer: _configuration["JWT:ValidIssuer"],
audience: _configuration["JWT:ValidAudience"],
expires: DateTime.Now.AddHours(3),
claims: authClaims,
signingCredentials: new SigningCredentials(authSigningKey, SecurityAlgorithms.HmacSha256)
);
return Ok(new
{
token = new JwtSecurityTokenHandler().WriteToken(token),
expiration = token.ValidTo
});
}
return Unauthorized();
}
我的启动文件包含这个,关于身份验证。
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.SaveToken = true;
options.RequireHttpsMetadata = false;
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true,
ValidateAudience = true,
ValidAudience = Configuration["JWT:ValidAudience"],
ValidIssuer = Configuration["JWT:ValidIssuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JWT:Secret"]))
};
});
--- 编辑 --- 我想对于生成令牌的人来说,他们还需要知道签名中的密钥,这确实增加了一些额外的安全性。
JWT 是独立的、按价值计算的令牌,一旦发布并交付给接收者就很难撤销它们。因此,您应该为您的令牌使用尽可能短的到期时间 - 最多几分钟或几小时。您应该避免以天或月为单位给出您的令牌到期时间。
请记住,包含到期时间的 exp 声明并不是唯一可用于验证的基于时间的声明。 nbf 声明包含“不早于”时间。如果当前时间早于 nbf 声明中的时间,则应拒绝令牌。另一个基于时间的声明是 iat - issued at。您可以使用此声明拒绝您认为太旧而无法与您的资源服务器一起使用的令牌。
在处理基于时间的声明时请记住,不同机器之间的服务器时间可能略有不同。在检查基于时间的值时,您应该考虑允许时钟偏差。这应该是几秒的值,我们不建议为此目的使用超过 30 秒,因为这更像是服务器问题,而不是常见的时钟偏差。
关于安全性,jWT 安全性在很大程度上取决于令牌的实现和使用方式。仅仅因为 JWT 包含加密签名,并不自动意味着它是安全的,或者您应该盲目地信任令牌。
您可以关注密码学的安全标准和安全级别:
JSON Web Token Best Current Practices and RFC 7518 JSON Web Algorithms (JWA)