【发布时间】:2019-04-29 12:28:38
【问题描述】:
根据this question,我正在使用下面的sn-p 对JWToken 进行签名和加密。
var claims = new Claim[] { new SomeClaimes() };
var scKey = Encoding.UTF8.GetBytes("SOME KEY");
var ecKeyTemp = Encoding.UTF8.GetBytes("SOME OTHER KEY");
byte[] ecKey = new byte[256 / 8];
Array.Copy(ecKeyTemp, ecKey, 256 / 8);
var tokenDescriptor = new SecurityTokenDescriptor {
Subject = new ClaimsIdentity(claims),
SigningCredentials = new SigningCredentials(
new SymmetricSecurityKey(
scKey),
SecurityAlgorithms.HmacSha512),
EncryptingCredentials = new EncryptingCredentials(
new SymmetricSecurityKey(
ecKey),
SecurityAlgorithms.Aes256KW,
SecurityAlgorithms.Aes256CbcHmacSha512),
Issuer = "My Jwt Issuer",
Audience = "My Jwt Audience",
IssuedAt = DateTime.UtcNow,
Expires = DateTime.Now.AddDays(7),
};
var tokenHandler = new JwtSecurityTokenHandler();
var token = tokenHandler.CreateJwtSecurityToken(tokenDescriptor);
var jwt = tokenHandler.WriteToken(token);
这是我的服务注册:
services
.AddAuthentication(o => {
o.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
o.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
o.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(cfg => {
cfg.RequireHttpsMetadata = false;
cfg.SaveToken = true;
cfg.TokenValidationParameters = new TokenValidationParameters {
ValidIssuer = "My Jwt Issuer",
ValidAudience = "My Jwt Audience",
IssuerSigningKey = new SymmetricSecurityKey(SameKeyAsGenerating)),
TokenDecryptionKey = new SymmetricSecurityKey(SameKeyAsGenerating),
ClockSkew = TimeSpan.Zero,
RequireSignedTokens = true,
RequireExpirationTime = true,
SaveSigninToken = true,
ValidateActor = true,
ValidateAudience = true,
ValidateIssuer = true,
ValidateIssuerSigningKey = true,
ValidateLifetime = true,
ValidateTokenReplay = true,
};
});
问题在于身份验证层将加密和未加密的令牌都作为授权进行身份验证。我的意思是当我创建一个没有EncryptingCredentials 的令牌(只是一个签名的令牌,没有加密)时,令牌仍然有效并且请求被授权。问题是如何强制认证层只接受签名加密的令牌,拒绝刚刚签名的未加密令牌?
更新:解决方案:
感谢sellotape's answer,我实现了这个JwtEncryptedSecurityTokenHandler:
public class JwtEncryptedSecurityTokenHandler : JwtSecurityTokenHandler {
[DebuggerStepThrough]
public override ClaimsPrincipal ValidateToken(string token, TokenValidationParameters validationParameters, out SecurityToken validatedToken) {
if (string.IsNullOrWhiteSpace(token))
throw new ArgumentNullException(nameof (token));
if (validationParameters == null)
throw new ArgumentNullException(nameof (validationParameters));
if (token.Length > MaximumTokenSizeInBytes)
throw new ArgumentException(
$"IDX10209: token has length: '{token.Length}' which is larger than the MaximumTokenSizeInBytes: '{MaximumTokenSizeInBytes}'.");
var strArray = token.Split(new[] { '.' }, 6);
if (strArray.Length == 5)
return base.ValidateToken(token, validationParameters, out validatedToken);
throw new SecurityTokenDecryptionFailedException();
}
}
并在Startup.ConfigureServices()中使用了新的处理程序:
.AddJwtBearer(cfg => {
cfg.RequireHttpsMetadata = false;
// other configurations...
cfg.SecurityTokenValidators.Clear();
cfg.SecurityTokenValidators.Add(new JwtEncryptedSecurityTokenHandler());
});
有关更多解释,请参阅接受的答案。
【问题讨论】:
标签: c# authentication .net-core jwt netcoreapp2.1