署名と暗号化でWebトークンを保護する必要があります。次のコード行を書きました。
var tokenHandler = new JwtSecurityTokenHandler();
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, owner.Name),
new Claim(ClaimTypes.Role, owner.RoleClaimType),
new Claim("custom claim type", "custom content")
}),
TokenIssuerName = "self",
AppliesToAddress = "http://www.example.com",
Lifetime = new Lifetime(now, now.AddSeconds(60 * 3)),
EncryptingCredentials = new X509EncryptingCredentials(new X509Certificate2(cert)),
SigningCredentials = new X509SigningCredentials(cert1)
};
var token = (JwtSecurityToken)tokenHandler.CreateToken(tokenDescriptor);
var tokenString = tokenHandler.WriteToken(token);
したがって、私はmakecert.exe
で生成されたいくつかの証明書を使用しています。次に、別のJwtSecurityTokenHandler
でトークン文字列を読み取ります。
var tokenHandlerDecr = new JwtSecurityTokenHandler();
var tok = tokenHandlerDecr.ReadToken(tokenString);
トークンのコンテンツは暗号化されていません(デバッガーのtok
変数でjsonを確認できます)。何が悪いのですか?トークンデータを暗号化する方法
私の理解では、MicrosoftのJWT実装は現在暗号化(署名のみ)をサポートしていません。
これは古い投稿ですが、誰かがまだ回答を探している場合に備えて、私の回答を追加しています。
この問題は Microsoft.IdentityModel.Tokens
バージョン5.1. 。トークンを暗号化するための暗号化資格情報を受け入れるCreateJwtSecurityToken
関数で使用可能なオーバーロードメソッドがあります。
受信者が署名を検証せず、そのままJWTを読み取ろうとすると、クレームは空になります。以下はコードスニペットです。
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
const string sec = "ProEMLh5e_qnzdNUQrqdHPgp";
const string sec1 = "ProEMLh5e_qnzdNU";
var securityKey = new SymmetricSecurityKey(Encoding.Default.GetBytes(sec));
var securityKey1 = new SymmetricSecurityKey(Encoding.Default.GetBytes(sec1));
var signingCredentials = new SigningCredentials(
securityKey,
SecurityAlgorithms.HmacSha512);
List<Claim> claims = new List<Claim>()
{
new Claim("sub", "test"),
};
var ep = new EncryptingCredentials(
securityKey1,
SecurityAlgorithms.Aes128KW,
SecurityAlgorithms.Aes128CbcHmacSha256);
var handler = new JwtSecurityTokenHandler();
var jwtSecurityToken = handler.CreateJwtSecurityToken(
"issuer",
"Audience",
new ClaimsIdentity(claims),
DateTime.Now,
DateTime.Now.AddHours(1),
DateTime.Now,
signingCredentials,
ep);
string tokenString = handler.WriteToken(jwtSecurityToken);
// Id someone tries to view the JWT without validating/decrypting the token,
// then no claims are retrieved and the token is safe guarded.
var jwt = new JwtSecurityToken(tokenString);
そして、これがトークンを検証/復号化するコードです:
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
const string sec = "ProEMLh5e_qnzdNUQrqdHPgp";
const string sec1 = "ProEMLh5e_qnzdNU";
var securityKey = new SymmetricSecurityKey(Encoding.Default.GetBytes(sec));
var securityKey1 = new SymmetricSecurityKey(Encoding.Default.GetBytes(sec1));
// This is the input JWT which we want to validate.
string tokenString = string.Empty;
// If we retrieve the token without decrypting the claims, we won't get any claims
// DO not use this jwt variable
var jwt = new JwtSecurityToken(tokenString);
// Verification
var tokenValidationParameters = new TokenValidationParameters()
{
ValidAudiences = new string[]
{
"536481524875-glk7nibpj1q9c4184d4n3gittrt8q3mn.apps.googleusercontent.com"
},
ValidIssuers = new string[]
{
"https://accounts.google.com"
},
IssuerSigningKey = securityKey,
// This is the decryption key
TokenDecryptionKey = securityKey1
};
SecurityToken validatedToken;
var handler = new JwtSecurityTokenHandler();
handler.ValidateToken(tokenString, tokenValidationParameters, out validatedToken);
次の例を試してください
2019年7月更新:.NET Core、Asp.net Core
1.JWTを作成する
_private string CreateJwt(string sub, string jti, string issuer, string audience)
{
var claims = new[]
{
new Claim(JwtRegisteredClaimNames.Sub, sub),
new Claim(JwtRegisteredClaimNames.Jti, jti),
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("SecretKeySecretKeySecretKeySecretKeySecretKeySecretKeySecretKeyS"));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var encryptingCredentials = new EncryptingCredentials(key, JwtConstants.DirectKeyUseAlg, SecurityAlgorithms.Aes256CbcHmacSha512);
var jwtSecurityToken = new JwtSecurityTokenHandler().CreateJwtSecurityToken(
issuer,
audience,
new ClaimsIdentity(claims),
null,
expires: DateTime.UtcNow.AddMinutes(5),
null,
signingCredentials: creds,
encryptingCredentials: encryptingCredentials
);
var encryptedJWT = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);
return encryptedJWT;
}
_
2. _Startup.cs
_のConfigureServices(IServiceCollection services)
に追加
_ services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = (string)Configuration.GetSection("JwtToken").GetValue(typeof(string), "Issuer"),
ValidAudience = (string)Configuration.GetSection("JwtToken").GetValue(typeof(string), "Audience"),
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("SecretKeySecretKeySecretKeySecretKeySecretKeySecretKeySecretKeyS")),
TokenDecryptionKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("SecretKeySecretKeySecretKeySecretKeySecretKeySecretKeySecretKeyS")),
ClockSkew = TimeSpan.FromMinutes(0),
};
});
_