我们自己的内部的几个系统做了单点登录(类似与第三方登录),从一个系统跳转到另一个系统时不需要再次登录,以前是把生成的token的SecurityKey直接复制到另一个系统然后验证token的,但是这样其他系统也可以使用SecurityKey生成token,安全性有一定问题,最近发现jwt加密方式可以改为rs256,这样就验证登录的系统就只需要公钥pubkey,而私钥prikey只会掌握到生成token的系统中。
修改SecurityKey类型
修改TokenAuthConfiguration类中的SecurityKey的类型为SecurityKey
1
2
3
4
5
6
7
8
9
10
11
12
13
public class TokenAuthConfiguration
{
-- public SymmetricSecurityKey SecurityKey { get; set; }
++ public SecurityKey SecurityKey { get; set; }
public string Issuer { get; set; }
public string Audience { get; set; }
public SigningCredentials SigningCredentials { get; set; }
public TimeSpan Expiration { get; set; }
}
修改加密方式
示例中我直接把公钥和私钥写在变量中了,应该放在配置文件中,注意公钥和私钥的长度至少为2048否则生成token会报错。
1
System.NotSupportedException HResult=0x80131515 Message=IDX10634: Unable to create the SignatureProvider. Algorithm: '[PII is hidden by default. Set the 'ShowPII' flag in IdentityModelEventSource.cs to true to reveal it.]', SecurityKey: '[PII is hidden by default. Set the 'ShowPII' flag in IdentityModelEventSource.cs to true to reveal it.]' is not supported.
修改XXXWebCoreModule中的ConfigureTokenAuth方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
private void ConfigureTokenAuth()
{
IocManager.Register<TokenAuthConfiguration>();
var tokenAuthConfig = IocManager.Resolve<TokenAuthConfiguration>();
++ var pubKey = "BgIAAACkAABSU0ExAAgAAAEAAQBtxB/X/mfyaWT+ZTqmfy3yKODczEpPuC+2xP8L98kU+ZRzBzx/ZNTiVbjiD3ypNE2a1KxUGXgBz6yRxUM8xHoWrAV9TrcuHX+vObkClaqTcw93KJH0xYaKjaRvrHfyR/F+vzyZHQqNXOL3hgploaJPvyVGLqwDdPL/XM1u9heBZVLEicMBcT/khJq0cbRjT4sjcV6sCg5JGYwrdjgJ3eXuXJjc/+FwVF/DErLibP5POadZptpg+YlN3zo4DRIj0gou4hUK/lbJ3Pi9OT21izB2ncE0VdDcZpPkqBkdEwxBfkHezquhBLMhwvNkMml1gF4pXVYHeCuY1IYdGK+BTFvW";
++ var priKey = "BwIAAACkAABSU0EyAAgAAAEAAQBtxB/X/mfyaWT+ZTqmfy3yKODczEpPuC+2xP8L98kU+ZRzBzx/ZNTiVbjiD3ypNE2a1KxUGXgBz6yRxUM8xHoWrAV9TrcuHX+vObkClaqTcw93KJH0xYaKjaRvrHfyR/F+vzyZHQqNXOL3hgploaJPvyVGLqwDdPL/XM1u9heBZVLEicMBcT/khJq0cbRjT4sjcV6sCg5JGYwrdjgJ3eXuXJjc/+FwVF/DErLibP5POadZptpg+YlN3zo4DRIj0gou4hUK/lbJ3Pi9OT21izB2ncE0VdDcZpPkqBkdEwxBfkHezquhBLMhwvNkMml1gF4pXVYHeCuY1IYdGK+BTFvW/xoSKQLnwF8DIiHM4waMUUjP+CUA20Xb1KqKsa05KASzK96M0QvBb9wqW0hnvYzkNHegScRNwqRbvVV7+IFKEFYxXgIZ6Mj+tpdk75OinC3RvCxuSbektX1WkyNXar+hqZoQ+ScM4+7Gc6cHCKC1/zgz1yUOiMrwSmuxMNGzN/aTvBmta1y06Kx7KmBfcJY8iP6UoCntiaAMbQryJnmuOupze9JdrVA9abjZ8hDiZf0ndV9WbBXtyUXzkENuKpmLRan3qnlWUApjx2kh8jUecc40W6+NFSbEQ7h/2ZrgYqRF/zSfL9fLBAWhXR1S4ezWQ4d6MAsDyxFroCu5S4nf3hdIawk6rsHOR4TMP/UGrBViyaPGc2T2qPOpgpp/Wk3CtJ3g7C37R+Vl8N40fdK22fuFN79RTn51RmnEK9ZDwXgrduVKyPhua49rawlvR+MqxG9Agmj7huW27DsIWoU1WJ3LiMoT2BkRy8DKDOpSfFJpJfShdwLY12K2RxoBZUeCm3sd8Nn5t8PbeYrtPmh+d1MYKvE/62nljKRJ7UuhrEdtHV+Fk5HKsfEGsShgaNvcZlOZxFlEdKFOQFhInmxDKvx4clGdCU8J0lui5YyfHQbe76JqMlAfqbCJaLcDv73Oe8dHlznLELXe0SVrGdY+Jla7880eoJTWNMj29sxJvix+38FT2ZfYnbBKGnS758UPG6TDQSdvPi9YT8TNczYT1bcI1CJVG+x/m3pGv/gLUjx8yA8jBD+SP8GviJ1c8nfHGTD1oAo9BobSfCqrbfGoyX1tyFXwYRg9OEGRsQ7TQKxyqdDjcONjQeQAcWxtO4z+5DExBwFSmITOpd0laJzy3L2HCDZnnv4KPmMPfG8F72q8pZCu1s5eLA+DIBQz9zSntNvAsH+4PV5w4mhiU1SO6roU57uAuNDX0hwCybrzDREaTpVI/S2DXrFxQ4tBJwlnjgqFFZ4ki0OUiuyIHODChiDd6QVkuTPu3ARtOIrH2oR+4TmYs9f6q+J3daFxYhJSGDiIoAn5XJpxEdUg7oRNmXcDEp6Tq/sv7iS02LAz9uc5fLDsNGHj/N0eECZZgOfyWKVeLMIFvb+ssjrBGuW/LrcidP8PXfD3SixEgd7Uf5QMM6GM+0Qgek62oW5iyTHG/FFKQXdgeXFUIt6Fvv+B/In+nPY2O5ZVuaGeGC6xOUw=";
++ var rsaPri = new System.Security.Cryptography.RSACryptoServiceProvider();
++ rsaPri.ImportCspBlob(Convert.FromBase64String(priKey));
++ tokenAuthConfig.SecurityKey = new RsaSecurityKey(rsaPri);
-- tokenAuthConfig.SecurityKey =
-- new SymmetricSecurityKey(
-- Encoding.ASCII.GetBytes(_appConfiguration["Authentication:JwtBearer:SecurityKey"]));
tokenAuthConfig.Issuer = _appConfiguration["Authentication:JwtBearer:Issuer"];
tokenAuthConfig.Audience = _appConfiguration["Authentication:JwtBearer:Audience"];
++ tokenAuthConfig.SigningCredentials =new SigningCredentials(tokenAuthConfig.SecurityKey, SecurityAlgorithms.RsaSha256);
-- tokenAuthConfig.SigningCredentials =
-- new SigningCredentials(tokenAuthConfig.SecurityKey, SecurityAlgorithms.HmacSha256);
tokenAuthConfig.Expiration = TimeSpan.FromDays(1);
}
修改abp验证token方式
修改了生成token的加密方式还必须修改验证token的方式,修改AuthConfigurer文件中的Configure方法
1
2
--IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(configuration["Authentication:JwtBearer:SecurityKey"])),
++IssuerSigningKey = new RsaSecurityKey(rsaPri),
第三方验证
这样生成的token就是采用rs256加密的了,验证的时候只需要使用公钥就行了 为了简便可以直接使用jwt包验证下
1
install-package JWT
1
2
3
4
5
6
7
RSACryptoServiceProvider rsaPub = new RSACryptoServiceProvider();
rsaPub.ImportCspBlob(Convert.FromBase64String(pubKey));
var json = new JwtBuilder()
.WithAlgorithm(new RS256Algorithm(rsaPub)) // symmetric
.MustVerifySignature()
.Decode(token);
Console.WriteLine(json);
本文会经常更新,请阅读原文: https://dashenxian.github.io/post/AbpJwt%E6%8E%88%E6%9D%83%E7%A0%81%E5%8A%A0%E5%AF%86%E6%96%B9%E5%BC%8F%E6%94%B9%E4%B8%BARS256 ,以避免陈旧错误知识的误导,同时有更好的阅读体验。
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 小神仙 (包含链接: https://dashenxian.github.io ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 (125880321@qq.com) 。