Web通用令牌JwtBuilder
JSON Web Token (JWT)是一個開放標(biāo)準(zhǔn)(RFC 7519),它定義了一種緊湊的、自包含的方式,用于作為JSON對象在各方之間安全地傳輸信息。該信息可以被驗證和信任,因為它是數(shù)字簽名的。
Nuget包:NewLife.Core、NewLife.Secrurity
源碼地址:
https://github.com/NewLifeX/X/blob/master/NewLife.Core/Web/JwtBuilder.cs
功能特性
主要功能特性:
Json格式簡單易用,JWT目前已經(jīng)成為最常見的web驗證方式;
主體部分可以按需增加多種數(shù)據(jù),滿足不同業(yè)務(wù)場景需要;
支持多種數(shù)字簽名方式,HS256/HS384/HS512密鑰短小,RS256/RS384/RS512安全性更高;
支持外擴(kuò)數(shù)字簽名方式,NewLife.Security 支持ES256/ES384/ES512;
應(yīng)用場景
使用JWT實現(xiàn)的SSO單點登錄工作流程
用戶首先前往SSO用戶中心進(jìn)行身份驗證,獲取JWT令牌,即可攜帶令牌訪問各應(yīng)用服務(wù)器。
令牌具有有效期,一般2小時過期。應(yīng)用服務(wù)器遇到過期令牌時,應(yīng)該拒絕提供服務(wù)。
SSO用戶中心實際上頒發(fā)兩個令牌,訪問令牌用于訪問各應(yīng)用服務(wù)器,刷新令牌用于在令牌過期之前請求SSO刷新令牌。
示例詳解
JwtBuilder設(shè)置Secret密鑰后(默認(rèn)算法HS256),通過Encode編碼匿名對象數(shù)據(jù),得到JWT令牌。
解碼時只需要設(shè)置密鑰,然后TryDecode即可,TryDecode返回JWT令牌驗證是否通過,如果不通過,message輸出參數(shù)指示錯誤內(nèi)容。
var builder = new JwtBuilder {IssuedAt = 1516239022.ToDateTime(),Expire = DateTime.MinValue,Secret = "Smart", };var token = builder.Encode(new { sub = "0201", name = "stone" }); Assert.NotNull(token); Assert.NotEmpty(token);var ts = token.Split('.'); Assert.Equal(3, ts.Length); Assert.Equal("eyJhbGciOiJIUzI1NiJ9", ts[0]); Assert.Equal("eyJzdWIiOiIwMjAxIiwibmFtZSI6InN0b25lIiwiaWF0IjoxNTE2MjM5MDIyfQ", ts[1]); Assert.Equal("mY2_rvQORkyYpK3f84liG2EDpaYY7pO43sRgcli381U", ts[2]);var builder2 = new JwtBuilder {Secret = builder.Secret, };ts = builder2.Parse(token); Assert.NotNull(ts); Assert.Equal(3, ts.Length);var rs = builder2.TryDecode(token, out var msg); Assert.True(rs); Assert.Null(msg);Assert.Null(builder2.Type); Assert.Equal("0201", builder2.Subject); Assert.Equal("stone", builder2["name"]);ES512擴(kuò)展
HS512安全性不夠,RS512密鑰太長導(dǎo)致令牌也很長。
此時最合適使用ES512,該算法封裝在 NewLife.Security 中,引用nuget包后,需要注冊算法:
JwtBuilder.RegisterAlgorithm("ES512", ECDsaHelper.SignSha512, ECDsaHelper.VerifySha512)
JwtBuilder.RegisterAlgorithm("ES256", ECDsaHelper.SignSha256, ECDsaHelper.VerifySha256); JwtBuilder.RegisterAlgorithm("ES384", ECDsaHelper.SignSha384, ECDsaHelper.VerifySha384); JwtBuilder.RegisterAlgorithm("ES512", ECDsaHelper.SignSha512, ECDsaHelper.VerifySha512);var prvKey = @"-----BEGIN PRIVATE KEY----- MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgevZzL1gdAFr88hb2 OF/2NxApJCzGCEDdfSp6VQO30hyhRANCAAQRWz+jn65BtOMvdyHKcvjBeBSDZH2r 1RTwjmYSi9R/zpBnuQ4EiMnCqfMPWiZqB4QdbAd0E7oH50VpuZ1P087G -----END PRIVATE KEY-----"; var pubKey = @"-----BEGIN PUBLIC KEY----- MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEEVs/o5+uQbTjL3chynL4wXgUg2R9 q9UU8I5mEovUf86QZ7kOBIjJwqnzD1omageEHWwHdBO6B+dFabmdT9POxg== -----END PUBLIC KEY-----";var builder = new JwtBuilder {Algorithm = "ES512",Type = "JWT",IssuedAt = 1516239022.ToDateTime(),Expire = DateTime.MinValue,Secret = prvKey, };var token = builder.Encode(new { sub = "1234567890", name = "NewLife", admin = true }); Assert.NotNull(token); Assert.NotEmpty(token);var ts = token.Split('.'); Assert.Equal(3, ts.Length); Assert.Equal("eyJhbGciOiJFUzUxMiIsInR5cCI6IkpXVCJ9", ts[0]); Assert.Equal("eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ik5ld0xpZmUiLCJhZG1pbiI6dHJ1ZSwiaWF0IjoxNTE2MjM5MDIyfQ", ts[1]); //Assert.Equal("xyCWz7tNjH4UUkxi7BqlWE4V857XA6SYC-ZFukvexvIgsGQt9SBcpdglz3NfhhrslOwF7HzWZHOJu3RrIFrDFA", ts[2]);var builder2 = new JwtBuilder {Algorithm = "ES512",Secret = pubKey, }; var rs = builder2.TryDecode(token, out var msg); Assert.True(rs); Assert.Null(msg);Assert.Equal("JWT", builder2.Type); Assert.Equal("1234567890", builder2.Subject); Assert.Equal("NewLife", builder2["name"]); Assert.True(builder2["admin"].ToBoolean());總結(jié)
應(yīng)用自己頒發(fā)自己驗證使用的場景,推薦使用HS512,簡單安全,且令牌長度較短,這是最常見的JWT在Web應(yīng)用場景。
應(yīng)用頒發(fā)令牌給多個第三方使用時,安全起見不能把HS512密鑰給對方,此時推薦使用ES512,安全性很高,并且令牌長度遠(yuǎn)比RS512要短,(但比HS512要長一些)。
總結(jié)
以上是生活随笔為你收集整理的Web通用令牌JwtBuilder的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 聊一聊Jmeter的简单使用
- 下一篇: NET问答: 如果动态构建 Query