介面的安全控制 (JWT) JSON Web Tokens
前言
如果你的介面是開放的,誰都可以成功呼叫,那麼會非常危險。因此除非你真的想做開放式服務,否則要對使用者的請求做許可權控制
舉例:假如我想自己寫一個“張三版新浪微博”的APP。
新浪微博開放了微博的介面,所有人可以呼叫這些介面“發微博”、“看微博”等。當然不是隨便呼叫,而是要到新浪微博的開放平臺後臺申請一個AppKey(或者AppId),申請成功後,新浪微博就會分配一個AppKey和一個App、AppSecret給你。這個AppKey就是供“張三版新浪微博”這個App用的,新浪微博的使用者也可以用同樣的使用者名稱密碼登入“張山版新浪微博”這個App發微博、看微博,和官方版本的新浪微博是互通的。
無論是認證還是授權,都需要傳遞認證資訊,對於認證來講就是AppKey、AppSecret,對於授權來講就是使用者的賬號、密碼。
介面傳輸這些認證資訊方法有很多,常用的有:
1> 每次請求,直接把“使用者名稱/AppKey”、“密碼/AppSecret”通過表單、QueryString或者報文頭傳遞;這種安全性比較差,因為隨時可以被截獲。
2> 首次先使用“使用者名稱/AppKey”、“密碼/AppSecret”獲取Access_Token(相當於SessionId,在伺服器端生成guid,用guid做key,用使用者名稱做value儲存到redis、memcached等地方),以後的請求都帶著Access_Token,Access_Token存在有效期,過時後要重新獲取Access_Token。缺點是Access_Token有過期重新登入的問題,而移動端app經常需要一段時間不用開啟還要能直接用。需要有一個類似於Session的中心回話伺服器。WebAPI也可以使用asp.net 的Session,但是不建議使用。
3> 登入時,伺服器端把“使用者名稱/AppKey”、“密碼/AppSecret”採用JWT等的加密後返回給客戶端,客戶端以後傳送請求的時候把JWT加密的內容放到請求中,服務端再解密獲取使用者名稱。優點是不需要會話狀態伺服器,有利於分散式部署,還有可以避免Session的過期問題,可以一直能用;缺點是一旦加密解密演算法洩露,會帶來安全性問題。(推薦)
為什麼使用JWT(JSON Web Tokens)
在傳統的基於session的使用者登入認證中,因為http是無狀態的,所以都是採用session方式。使用者登入成功,服務端會建立一個session,當然會給客戶端一個sessionId,客戶端會把sessionId儲存在cookie中,每次請求都會攜帶這個sessionId。
cookie+session這種模式通常是儲存在記憶體中,而且服務從單服務到多服務會面臨的session共享問題,隨著使用者量的增多,開銷就會越大。而JWT不是這樣的,只需要服務端生成token,客戶端儲存這個token,每次請求攜帶這個token,服務端認證解析就可。
JWT 是一種無狀態的分散式的身份驗證方式,與 Session 相反,Jwt 將使用者資訊存放在 Token 的 payload 欄位儲存在客戶端,通過 RSA 加密的方式,保證資料不會被篡改,驗證資料有效性。
我們需要做的第一件事就是讓客戶端通過他們的賬號密碼交換token。這裡有2種可能的方法在RESTful API裡面。第一種是使用POST請求來通過驗證,使服務端傳送帶有token的響應。除此之外,你可以使用GET請求,這需要他們使用引數提供憑證(指URL),或者更好的使用請求頭。
JWT(Json Web Token)是現在流行的一種對Restful介面進行驗證的機制的基礎。JWT的特點:把使用者資訊放到一個JWT字串中,使用者資訊部分是明文的,再加上一部分簽名區域,簽名部分是伺服器對於“明文部分+祕鑰”加密的,這個加密資訊只有伺服器端才能解析。使用者端只是儲存、轉發這個JWT字串。如果客戶端篡改了明文部分,那麼伺服器端解密時候會報錯。
JWT由三塊組成,可以把使用者名稱、使用者Id等儲存到Payload部分
頭:Header
JWT第一部分是header,header主要包含兩個部分,alg指加密型別,可選值為HS256
、RSA
等等,typ=JWT
為固定值,表示token的型別。
{
"typ": "JWT",
"alg": "HS256"
}
載體:Payload
JWT第二部分是Payload,Payload 部分也是一個 JSON 物件,它是token的詳細內容,用來存放實際需要傳遞的資料,一般包括:iss
(發行者 即:JWT簽發者),exp
(過期時間 即:JWT的過期時間,這個過期時間必須要大於簽發時間), sub
(使用者資訊)aud
(接收者 即:接收JWT的一方),iat
(簽發時間 即:JWT的簽發時間)
nbf (生效時間 即:定義在什麼時間之前,該jwt都是不可用的)
jti (編號 即:JWT的唯一身份標識【值一般是GUID】,主要用來作為一次性token,從而回避重放攻擊:具體做法就是使用者請求一次,然後我們獲取這個jti的值,然後給這個值加入黑名單【在Redis中設定一個黑名單表】使用者第二次用這個Token來請求,我們在得到這個jti的值,去黑名單中查詢下是否有這個值,如果有值則表示是重放請求)
以及其他資訊,詳細介紹請參考官網,也可以包含自定義欄位。JWT 規定了以上7個官方欄位,供選用
例如:我們可以自定義一個Payload
{
"sub": "招商銀行",
"name": "張三",
"admin": true,
"jti": "2ab2dc85-0589-4174-b86e-b23dc9ae82a0",
"iat": 1542037098, //簽發日期的時間戳
"exp": 1542040698 //過期日期的時間戳
}
簽名:Signature
JWT第三部分是Signature,Signature 部分是對前兩部分的簽名,防止資料篡改。
這部分的內容是這樣計算得來的:
首先,需要指定一個金鑰(secret)。這個金鑰只有伺服器才知道,不能洩露給使用者。然後,使用 Header 裡面指定的簽名演算法(預設是 HMAC SHA256),按照下面的公式產生簽名。
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
算出簽名以後,把 Header、Payload、Signature 三個部分拼成一個字串,每個部分之間用"點"(.
)分隔,就可以返回給使用者。
Token案例
using JWT;
using JWT.Algorithms;
using JWT.Serializers;
using Microsoft.AspNetCore.Mvc;
namespace JwtApp.Controllers
{
[Route("api/[controller]")]
public class HomeController : Controller
{
//建立Token
[Route(nameof(CreateToken))]
public IActionResult CreateToken()
{
var jti = Guid.NewGuid();
var exp = (DateTime.UtcNow.AddSeconds(100) - new DateTime(1970, 1, 1)).TotalSeconds;
var payload = new Dictionary<string, object>
{
{ "sub", "招商銀行" },
{ "userName", "張三" },
{ "admin",true},
{ "jti", jti},
{ "exp",exp}
};
var secret = "GQDstcKsx0NHjPOuXOYg5MbeJ1XT0uFiwDVvVBrk";//祕鑰:不要洩露
IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
IJsonSerializer serializer = new JsonNetSerializer();
IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);
var token = encoder.Encode(payload, secret);
return Content(token);
}
//解密Token
[Route(nameof(DecryptToken))]
public IActionResult DecryptToken(string token)
{
var secret = "GQDstcKsx0NHjPOuXOYg5MbeJ1XT0uFiwDVvVBrk";//祕鑰:不要洩露
try
{
IJsonSerializer serializer = new JsonNetSerializer();
IDateTimeProvider provider = new UtcDateTimeProvider();
IJwtValidator validator = new JwtValidator(serializer, provider);
IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder);
var json = decoder.Decode(token, secret, verify: true);
return Content(json);
}
catch (FormatException)
{
return Content("Token格式無效");
}
catch (TokenExpiredException)
{
return Content("Token已經過期");
}
catch (SignatureVerificationException)
{
return Content("Token無效");
}
}
}
}
相關推薦
介面的安全控制 (JWT) JSON Web Tokens
前言 如果你的介面是開放的,誰都可以成功呼叫,那麼會非常危險。因此除非你真的想做開放式服務,否則要對使用者的請求做許可權控制 舉例:假如我想自己寫一個“張三版新浪微博”的APP。 新浪微博開放了微博的介面,所有人可以呼叫這些介面“發微博”、“看微博”等。當然不是隨便呼叫,而
Pro Android學習筆記(二八) 使用者介面和控制(16) GridLayout
網格佈局:GridLayout我個人覺得GridLayout的設計還不很完善,每個網格的大小,由填充的cell決定,即預設是wrap很容易整個GridLayout超出螢幕。下面是一個例子:<?xml version="1.0" encoding="utf-8"?><GridLayout xm
Pro Android學習筆記(二五):使用者介面和控制(13):LinearLayout和TableLayout
佈局Layout Layout是容器,用於對所包含的view進行佈局。layout是view的子類,所以可以作為view嵌入到其他的layout中。Android的layout有LinearLayout、TableLayout,RelativeLayout、FrameLayout、GridLayout。 線
2019測試指南-web應用程式安全測試(二)檢視Web伺服器圖元檔案的資訊洩漏
浪費了“黃金五年”的Java程式設計師,還有救嗎? >>>
JSON Web Tokens(JWT)
header xiaomi 含義 安全 glog format creation json hash 現在API越來越流行,如何安全保護這些API? JSON Web Tokens(JWT)能提供基於JSON格式的安全認證。它有以下特點: JWT是跨不同語言的,JWT可以
Json Web Token(JWT)
.json import form hid color 執行 加密方法 isa dep Json web token (JWT),是為了在網絡應用環境間傳遞聲明而執行的一種基於JSON的開放標準((RFC 7519)。該token被設計為緊湊且安全的,特別適用於分布式站點的
JSON Web Token(JWT)的詳解
1、傳統身份驗證和JWT的身份驗證 傳統身份驗證: HTTP 是一種沒有狀態的協議,也就是它並不知道是誰是訪問應用。這裡我們把使用者看成是客戶端,客戶端使用使用者名稱還有密碼通過了身份驗證,不過下回這個客戶端再發送請求時候,還得再驗證一下。 解決的方法就是,
JWT(JSON WEB TOKENS)-一種無狀態的認證機制
轉載自:http://www.tuicool.com/articles/R7Rj6r3 JWT(JSON Web Tokens ) ———— 一種無狀態的認證機制 一、什麼是JWT? JWT是一種用於雙方之間傳遞安全資訊的簡潔的、URL安全的表述性宣告規範。JWT作
JSON Web Token(JWT)原理和用法介紹
JSON Web Token(JWT)是目前最流行的跨域身份驗證解決方案。今天給大家介紹一下JWT的原理和用法。 一、跨域身份驗證 Internet服務無法與使用者身份驗證分開。一般過程如下。 1. 使用者向伺服器傳送使用者名稱和密碼。 2. 驗證伺服器後,相關資料(如使用者角色,登入時間等)將儲存在
JSON Web Token(JWT)使用步驟說明 JSON Web Token(JWT)原理和用法介紹
在JSON Web Token(JWT)原理和用法介紹中,我們瞭解了JSON Web Token的原理和用法的基本介紹。本文我們著重講一下其使用的步驟: 一、JWT基本使用 Gradle下依賴 : compile 'com.auth0:java-jwt:3.4.0' 示例介紹: im
Spring Boot入門教程(五十一): JSON Web Token(JWT)
一:認證 在瞭解JWT之前先來回顧一下傳統session認證和基於token認證。 1.1 傳統session認證 http協議是一種無狀態協議,即瀏覽器傳送請求到伺服器,伺服器是不知道這個請求是哪個使用者發來的。為了讓伺服器知道請求是哪個使用者發來的,需要讓使用者提供
JWT(JSON Web Tokens)的使用
由來 做了這麼長時間的web開發,從JAVA EE中的jsf,spring,hibernate框架,到spring web MVC,到用php框架thinkPHP,到現在的nodejs,我自己的看法是越來越喜歡乾淨整潔的web層,之前用jsf開發做view層的時候,用的
JSON WEB TOKEN(JWT)的分析
工作 增加 敏感信息 我們 一段時間 數據量 數據結構 定時 session JSON WEB TOKEN(JWT)的分析 一般情況下,客戶的會話數據會存在文件中,或者引入redis來存儲,實現session的管理,但是這樣操作會存在一些問題,使用文件來存儲的時候,在多臺機
WEB安全實戰(四)關於 Cookie
round url 主動 gin 加密 文章 日期 就會 dex 前言 這幾天中,一直再跟漏洞打交道,而在這些漏洞中,出現的最多的就是 Cookie 和 Session 了。這篇文章就簡單的介紹一些 Cookie 中最經常使用的四個屬性。也算是為興許的文章做一個
支持多用戶web終端實現及安全保障(nodejs)
ant 設置 寬高 處理 out locking nec tdi 背景 背景 terminal(命令行)作為本地IDE普遍擁有的功能,對項目的git操作以及文件操作有著非常強大的支持。對於WebIDE,在沒有web偽終端的情況下,僅僅提供封裝的命令行接口是完全不能滿
web 安全問題(二):XSS攻擊
class http amp 輸入 img xss攻擊 site lov 防禦 上文說完了CSRF攻擊,本文繼續研究它的兄弟XSS攻擊。 什麽是XSS攻擊 XSS攻擊的原理 XSS攻擊的方法 XSS攻擊防禦的手段 什麽是XSS攻擊 XSS攻擊全名(Cross-Site-Sc
Apache Shiro Web許可權控制(1)
Shiro官方文件:http://shiro.apache.org/web.html#Web-configuration ①建立一個maven web工程 ②新增依賴 <dependencies> <dependency> <groupId&g
jmeter介面效能測試(4)----提取json中的資料並應用到斷言中
介面資訊如下: 執行介面後在檢視結果樹種檢視響應資料,檢視方式選擇:JSON Path Tester 我們要在json中提取如下的資料: 檢視json體的路徑關係,在JSON path Expression中輸入路徑,關注是否能得到想要的數值。如:我們想要獲取上圖中的n
web安全系列(一):XSS 攻擊基礎及原理
跨站指令碼攻擊(XSS)是客戶端指令碼安全的頭號大敵。本文章深入探討 XSS 攻擊原理,下一章(XSS 攻擊進階)將深入討論 XSS 進階攻擊方式。 本系列將持續更新。 XSS 簡介 XSS(Cross Site Script),全稱跨站指令碼攻擊,為了與 CSS(Cascading Style Sheet)
Web安全系列(二):XSS 攻擊進階(初探 XSS Payload)
什麼是 XSS Payload 上一章我談到了 XSS 攻擊的幾種分類以及形成的攻擊的原理,並舉了一些淺顯的例子,接下來,我就闡述什麼叫做 XSS Payload 以及從攻擊者的角度來初探 XSS 攻擊的威力。 在黑客 XSS 攻擊成功之後,攻擊者能夠對使用者當前瀏覽的頁面植入各種惡意指令碼,通過惡意指令碼來