1. 程式人生 > >介面的安全控制 (JWT) JSON Web Tokens

介面的安全控制 (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指加密型別,可選值為HS256RSA等等,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 TokensJWT

header xiaomi 含義 安全 glog format creation json hash 現在API越來越流行,如何安全保護這些API? JSON Web Tokens(JWT)能提供基於JSON格式的安全認證。它有以下特點: JWT是跨不同語言的,JWT可以

Json Web TokenJWT

.json import form hid color 執行 加密方法 isa dep Json web token (JWT),是為了在網絡應用環境間傳遞聲明而執行的一種基於JSON的開放標準((RFC 7519)。該token被設計為緊湊且安全的,特別適用於分布式站點的

JSON Web TokenJWT的詳解

1、傳統身份驗證和JWT的身份驗證 傳統身份驗證:       HTTP 是一種沒有狀態的協議,也就是它並不知道是誰是訪問應用。這裡我們把使用者看成是客戶端,客戶端使用使用者名稱還有密碼通過了身份驗證,不過下回這個客戶端再發送請求時候,還得再驗證一下。 解決的方法就是,

JWTJSON WEB TOKENS-一種無狀態的認證機制

轉載自:http://www.tuicool.com/articles/R7Rj6r3 JWT(JSON Web Tokens ) ———— 一種無狀態的認證機制 一、什麼是JWT? JWT是一種用於雙方之間傳遞安全資訊的簡潔的、URL安全的表述性宣告規範。JWT作

JSON Web TokenJWT原理和用法介紹

JSON Web Token(JWT)是目前最流行的跨域身份驗證解決方案。今天給大家介紹一下JWT的原理和用法。 一、跨域身份驗證 Internet服務無法與使用者身份驗證分開。一般過程如下。 1. 使用者向伺服器傳送使用者名稱和密碼。 2. 驗證伺服器後,相關資料(如使用者角色,登入時間等)將儲存在

JSON Web TokenJWT使用步驟說明 JSON Web TokenJWT原理和用法介紹

在JSON Web Token(JWT)原理和用法介紹中,我們瞭解了JSON Web Token的原理和用法的基本介紹。本文我們著重講一下其使用的步驟: 一、JWT基本使用 Gradle下依賴 : compile 'com.auth0:java-jwt:3.4.0' 示例介紹: im

Spring Boot入門教程(五十一): JSON Web TokenJWT

一:認證 在瞭解JWT之前先來回顧一下傳統session認證和基於token認證。 1.1 傳統session認證 http協議是一種無狀態協議,即瀏覽器傳送請求到伺服器,伺服器是不知道這個請求是哪個使用者發來的。為了讓伺服器知道請求是哪個使用者發來的,需要讓使用者提供

JWTJSON Web Tokens的使用

由來 做了這麼長時間的web開發,從JAVA EE中的jsf,spring,hibernate框架,到spring web MVC,到用php框架thinkPHP,到現在的nodejs,我自己的看法是越來越喜歡乾淨整潔的web層,之前用jsf開發做view層的時候,用的

JSON WEB TOKENJWT的分析

工作 增加 敏感信息 我們 一段時間 數據量 數據結構 定時 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 攻擊成功之後,攻擊者能夠對使用者當前瀏覽的頁面植入各種惡意指令碼,通過惡意指令碼來