微服务之间调用的安全认证-jwt
在微服務(wù)架構(gòu)下,如何保證服務(wù)與服務(wù)之間調(diào)用的安全性呢?不是說(shuō)你想調(diào)用就可以調(diào)用,一定要有認(rèn)證機(jī)制,即只有我們內(nèi)部服務(wù)發(fā)出的請(qǐng)求,才可以調(diào)用我們的接口。
什么是JWT
JWT(Json Web Token)是為了在網(wǎng)絡(luò)應(yīng)用環(huán)境間傳遞聲明而執(zhí)行的一種基于Json的開(kāi)放標(biāo)準(zhǔn)。JWT的聲明一般被用來(lái)在身份提供者和服務(wù)提供者間傳遞被認(rèn)證的用戶(hù)身份信息,以便于從資源服務(wù)器獲取資源。
比如用在用戶(hù)登錄上時(shí),基本思路就是用戶(hù)提供用戶(hù)名和密碼給認(rèn)證服務(wù)器,服務(wù)器驗(yàn)證用戶(hù)提交信息的合法性;如果驗(yàn)證成功,會(huì)產(chǎn)生并返回一個(gè)Token,用戶(hù)可以使用這個(gè)Token訪(fǎng)問(wèn)服務(wù)器上受保護(hù)的資源。
JWT由三部分構(gòu)成,第一部分稱(chēng)為頭部(Header),第二部分稱(chēng)為消息體(Payload),第三部分是簽名(Signature)。一個(gè)JWT生成的Token格式為:
token = encodeBase64(header) + '.' + encodeBase64(payload) + '.' + encodeBase64(signature)頭部的信息通常由兩部分內(nèi)容組成,令牌的類(lèi)型和使用的簽名算法:
{ "alg": "HS256", "typ": "JWT" }消息體中可以攜帶一些你需要的信息,比如用戶(hù)ID。因?yàn)槟愕弥肋@個(gè)Token是哪個(gè)用戶(hù)的,如下:
{ "id": "94256", "name": "DaDudu", "role": teacher }簽名是用來(lái)判斷消息在傳遞的路上是否被篡改,從而保證數(shù)據(jù)的安全性,如下:
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)通過(guò)這三部分就組成了我們的Json Web Token。
創(chuàng)建統(tǒng)一的認(rèn)證服務(wù)
生成Token是在進(jìn)行用戶(hù)身份認(rèn)證之后,通過(guò)用戶(hù)的ID來(lái)生成一個(gè)Token,這個(gè)Token采用RSA加密的方式進(jìn)行加密,Token的內(nèi)容包括用戶(hù)的ID和過(guò)期時(shí)間。
public static String getToken(String uid, int exp) {return Jwts.builder().setSubject(uid).setExpiration(new Date(System.currentTimeMillis() + 1000 *60 *exp)).signWith(SignatureAlgorithm.RS512, priKey).compact(); }檢查T(mén)oken則是根據(jù)調(diào)用方帶來(lái)的Token檢查是否為合法用戶(hù),就是對(duì)Token進(jìn)行解密操作,能解密并且在有效期內(nèi)表示合法,合法則返回用戶(hù)ID。
public JWTResult checkToken(String token) {try {Claims claims = Jwts.parser().setSigningKey(pubKey).parseClaimsJws(token).getBody();String sub = claims.get("sub", String.class);return new JWTResult(true, sub, " 合法請(qǐng)求 ", ResponseCode.SUCCESS_CODE.getCode());} catch (ExpiredJwtException e) {// 在解析 JWT 字符串時(shí),如果’過(guò)期時(shí)間字段’已經(jīng)早于當(dāng)前時(shí)間,// 將會(huì)拋出 ExpiredJwtException 異常,說(shuō)明本次請(qǐng)求已經(jīng)失效return new JWTResult(false, null, "token 已過(guò)期 ", ResponseCode.TOKEN_TIMEOUT_CODE.getCode());} catch (SignatureException e) {// 在解析 JWT 字符串時(shí),如果密鑰不正確,將會(huì)解析失敗,拋出 SignatureException 異常,說(shuō)明該 JWT 字符串是偽造的return new JWTResult(false, null, " 非法請(qǐng)求 ", ResponseCode.NO_AUTH_CODE.getCode()); } catch (Exception e) { return new JWTResult(false, null, " 非法請(qǐng)求 ", ResponseCode.NO_AUTH_CODE.getCode()); }}刷新RSA公鑰及私鑰的作用是防止公鑰、私鑰泄露,公鑰、私鑰一般是寫(xiě)死的,不過(guò)我們可以做成配置的。集成配置管理中心后,可以對(duì)公鑰、私鑰進(jìn)行動(dòng)態(tài)修改,修改之后需要重新初始化公鑰、私鑰的對(duì)象信息。
服務(wù)提供方進(jìn)行調(diào)用認(rèn)證
服務(wù)提供方就是provider。服務(wù)消費(fèi)方消費(fèi)接口時(shí),provider需要對(duì)其進(jìn)行身份驗(yàn)證,驗(yàn)證通過(guò)才可以讓它消費(fèi)接口。
服務(wù)消費(fèi)方申請(qǐng)Token
目前服務(wù)提供方已經(jīng)開(kāi)啟了調(diào)用認(rèn)證,這意味著如果現(xiàn)在直接調(diào)用接口會(huì)被攔截,所以在調(diào)用之前需要進(jìn)行認(rèn)證,即獲取Token并將其放到請(qǐng)求頭中與請(qǐng)求頭一起傳輸才可以調(diào)用接口。
總結(jié)
以上是生活随笔為你收集整理的微服务之间调用的安全认证-jwt的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 《java程序设计基础》使用Reader
- 下一篇: 2019年日本上班的你必须知道的社会保障