emqx啟用JWT令牌認證(包含hmac-based和public-key)

来源:https://www.cnblogs.com/yusishi/archive/2022/10/15/16519273.html
-Advertisement-
Play Games

emqx連接啟用jwt令牌認證 jwt令牌 概述 JWT 即 JSON Web Tokens 是一種開放的,用於在兩方之間安全地表示聲明的行業標準的方法(RFC 7519)。 組成 令牌的形式 xxx.yyy.zzz eyJhbGciOiJIUzI1NiJ9 .eyJleHAiOjE2NjU0Nzc ...


emqx連接啟用jwt令牌認證

jwt令牌

概述

JWT 即 JSON Web Tokens
是一種開放的,用於在兩方之間安全地表示聲明的行業標準的方法(RFC 7519)。

組成

令牌的形式 xxx.yyy.zzz

eyJhbGciOiJIUzI1NiJ9
.eyJleHAiOjE2NjU0Nzc4NjEsInVzZXIiOiJtcXR0LWNsaWVudCIsImlhdCI6MTY2NTQ3Njg2MX0
.S9ZrrAk2zmUC2zQ7YNcGwhojLOKV5Bhe3zrMv6rQuzE

由三部分組成,先後分別為HEADER、PAYLOAD、VERIFY SIGNATURE
簡單的說,xxx和yyy是對JSON字元串進行base64加密得到,
zzz是由“xxx.yyy”加密得到,最後組裝成 xxx.yyy.zzz

HEADER(頭部)由 ALGORITHM(演算法) 和 TOKEN TYPE(令牌類型) 組成

{
  "alg": "HS256",
  "typ": "JWT"
}

xxx由HEADER使用Base64加密得到
alg : 表示簽名的演算法
typ : 表示令牌的類型

PAYLOAD

PAYLOAD(負載)存放一些用戶信息,但不能存放敏感信息,因為負載中的信息是公開的
yyy由PAYLOAD使用Base64加密得到

VERIFY SIGNATURE

VERIFY SIGNATURE(驗證簽名)
zzz由前兩部分使用簽名加密得到,即對 xxx.yyy 加密,中間連接的“.”是需要的

生成JWT

依賴

        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.6.0</version>
        </dependency>

代碼

api使用方式是生成JwtBuilder對象 然後調用compact()方法,就能得到JWT.JWT主要由三部分組成,那麼代碼中同理需要對三部分進行構造,使用api時,主要是對PAYLOAD和VERIFY SIGNATURE進行賦值.

        Instant now = Instant.now();

        Map<String, Object> claims = new HashMap<>();
        claims.put("user", "mqtt-client");

        String compact = Jwts.builder()
                .setClaims(claims) // 自定義聲明
                .setIssuedAt(Date.from(now)) // 對標準中的聲明賦值,設置簽發時間
                .setExpiration(Date.from(now.plusSeconds(1000))) // 對標準中的聲明賦值,設置過期時間
                .signWith(SignatureAlgorithm.HS256, "NmVlR3l2T3BiQnBXMi9veVBlcTZWaEpES09XTzdoWnM=") // 設置簽名
                .compact();
        System.out.println(compact);

tips

  1. 值得註意的一點是:不要在 setXxx(標準中的聲明) 之後調用 setClaims,因為這兩個方法會覆蓋所有已設置的聲明
  2. PAYLOAD可以分為payload和claims,但是兩者既不能都為空也不能都存在,同時只能存在一個,否則將會報錯.
    image
  3. 可以不手動設置HEADER,api中會自動設置,當然,自己手動設置HEADER屬性也可以
  4. HEADER中的alg會隨構造的簽名自動變更
  5. 關於預設的claims

根據RFC 7519協議標準 我們獲取到JWT標準中claims的欄位,這些欄位是可選的

1. iss :Issuer,頒發者
2. sub : Subject,主題
3. aud : Audience,受眾
4. exp :Expiration Time,過期時間
5. nbf :Not Before,不能被接受處理的時間
6. iat :Issued At,發佈時間
7. jti :JWT ID
這些claims欄位可以根據需要去設置,也可以自己定義claim

emqx的安裝

根據環境自己選擇下載

tips

  1. 如果連接不上服務,建議查看8083埠是否打開
  2. 如果dashborad無法打開,建議查看18083埠是否打開

hmac-based方式驗證

概述

emqx中hmac-based方式,表明 JWT 將使用對稱密鑰生成簽名和校驗簽名(支持 HS256、HS384 和 HS512 演算法),上述的JWT令牌使用的是SignatureAlgorithm.HS256,使用該方式驗證,上述代碼可以直接使用

HS256("HS256", "HMAC using SHA-256", "HMAC", "HmacSHA256", true)

開啟驗證

  • Secret,用於校驗簽名的密鑰,與生成簽名時使用的密鑰相同
  • Secret Base64 Encode,表明 Secret 是否經過 Base64 加密,即 EMQX 在使用 Secret 校驗簽名時是否需要先對其進行 Base64 解密

image

public-key方式驗證

概述

emqx中public-key方式,表明 JWT 使用私鑰生成簽名,需要使用公鑰校驗簽名(支持 RS256、RS384、RS512、ES256、ES384 和 ES512 演算法),對於生成的JWT令牌來說,加密方式我這裡換成了RSA,即SignatureAlgorithm.RS256

RS256("RS256", "RSASSA-PKCS-v1_5 using SHA-256", "RSA", "SHA256withRSA", true)

其原理是對JWT令牌使用私鑰加簽,然後將公鑰配置在emqx上,連接時用emqx中的公鑰驗簽,防止信息被篡改

開啟驗證

  • Public Key,指定用於校驗簽名的 PEM 格式的公鑰
    image

PEM格式的公鑰私鑰生成

首先,需要在windows上安裝openssl,然後通過指令生成pem格式文件

    openssl生成私鑰命令: openssl genrsa -out rsa_private_key.pem 1024
    openssl生成公鑰命令: openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

image
image
PEM格式的私鑰Java代碼中是沒辦法直接使用的,需要手動或者通過方法變成連續的字元串

MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAMGL0LhjNqcK32eTHLrmJovihQjIGYJrqw+GsAwgQxLq2SUZxEkbNNOK8OnR5S8g3PUdHraqWlthiLWLfZB3HjsIhq7if9giln9NkCs8hrbIxaghJTB3zo/L7+Bq2eL3zx5ke9ExceG9Xb7d5RCQ1d/xmzKNZqgC0tOGiiaLrU89AgMBAAECgYBhCNDu8MbgvqG80tOvnF2s+jdKbM/lREex9AvlOHOIU3fkkuOG5333pQwdnh7yHt7IgP36BLRiZibdJf8g46eif+Azf7nmH9fW4tQagdjoVoZGz+9Vp9m2ERRsy7Po50d4C5WQdKbxWiSE6qTWtrqIxpZCGkhPyuWsPaYNTQ2TXQJBAOSM1wFtXD3ivSS+SjgTessQdWHaK/xRvN+glr6JJhzK0Tl6xb8IftFJjBi4RY3e1eAciYVhnTDpQfhKGrRumVMCQQDYyrfldKPxXwWelAVbSAepOrU+Iod0DUKpCRS83dGMQFLI/fmAdNL2AY2drr3w6xdeAWTAagB4sKzWoyEMShMvAkEAr42PSUVbaR3U83hHQjOUSo5l27fduX5/eba8k7Z9U/hmJaSsaER6RQAdYI+KvaLA3diNuap1N7C0P6eMQ7QAiQJBAICYh0shzFnSLsgpL6A88uZsf7Qy0TyC3SbdzyJVRga25SR6mvSa18S7mSCO1fbBzSOjGfuVJWByFKRhMapTilsCQQCaVsZ/2QrlzeHaAfWbMSVi8ml3JlF1nCOyiNtypNJB+HXXrE6SJc3vRnwPIku1N6uduQF2W0ypykCzDdcqGkuF

PEM格式中帶有換行符,處理時需要註意,此時連接的字元串就位私鑰

代碼

package com.mio.mqtt.util;

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import sun.misc.BASE64Decoder;


import java.security.KeyFactory;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.time.Instant;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class JWTUtils {
    public static void main(String[] args) {
        Instant now = Instant.now();

        Map<String, Object> claims = new HashMap<>();
        claims.put("user", "mqtt-client");

        String privateKey = "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAMGL0LhjNqcK32eTHLrmJovihQjIGYJrqw+GsAwgQxLq2SUZxEkbNNOK8OnR5S8g3PUdHraqWlthiLWLfZB3HjsIhq7if9giln9NkCs8hrbIxaghJTB3zo/L7+Bq2eL3zx5ke9ExceG9Xb7d5RCQ1d/xmzKNZqgC0tOGiiaLrU89AgMBAAECgYBhCNDu8MbgvqG80tOvnF2s+jdKbM/lREex9AvlOHOIU3fkkuOG5333pQwdnh7yHt7IgP36BLRiZibdJf8g46eif+Azf7nmH9fW4tQagdjoVoZGz+9Vp9m2ERRsy7Po50d4C5WQdKbxWiSE6qTWtrqIxpZCGkhPyuWsPaYNTQ2TXQJBAOSM1wFtXD3ivSS+SjgTessQdWHaK/xRvN+glr6JJhzK0Tl6xb8IftFJjBi4RY3e1eAciYVhnTDpQfhKGrRumVMCQQDYyrfldKPxXwWelAVbSAepOrU+Iod0DUKpCRS83dGMQFLI/fmAdNL2AY2drr3w6xdeAWTAagB4sKzWoyEMShMvAkEAr42PSUVbaR3U83hHQjOUSo5l27fduX5/eba8k7Z9U/hmJaSsaER6RQAdYI+KvaLA3diNuap1N7C0P6eMQ7QAiQJBAICYh0shzFnSLsgpL6A88uZsf7Qy0TyC3SbdzyJVRga25SR6mvSa18S7mSCO1fbBzSOjGfuVJWByFKRhMapTilsCQQCaVsZ/2QrlzeHaAfWbMSVi8ml3JlF1nCOyiNtypNJB+HXXrE6SJc3vRnwPIku1N6uduQF2W0ypykCzDdcqGkuF";


        try {

            // 獲取秘鑰
            BASE64Decoder base64Decoder=new BASE64Decoder();
            byte[] bytes = base64Decoder.decodeBuffer(privateKey);
            KeySpec spec = new PKCS8EncodedKeySpec(bytes);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");


            String compact = Jwts.builder()
                    .setClaims(claims) // 自定義聲明
                    .setIssuedAt(Date.from(now)) // 對標準中的聲明賦值,設置簽發時間
                    .setExpiration(Date.from(now.plusSeconds(1000))) // 對標準中的聲明賦值,設置過期時間
                    .signWith(SignatureAlgorithm.RS256, keyFactory.generatePrivate(spec)) // 設置簽名
                    .compact();
            System.out.println(compact);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

本文來自博客園,作者:狸子橘花茶,轉載請註明原文鏈接:https://www.cnblogs.com/yusishi/p/16519273.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 設置MySQL 創建資料庫,預設為UTF-8 下載地址:https://downloads.mysql.com/archives/installer/ 安裝 網站上只有 x86 沒有 x64 位,之前下了 x64 的zip 包,配置比較麻煩,其實這個 x86 包裡面,已經包含了 x64的包 我這邊選 ...
  • 邏輯存儲結構 邏輯存儲結構圖 表空間 表空間文件在Linux下存放在 /var/lib/mysql文件中的 xxx.ibd 文件就是表空間文件 表空間文件用來存儲,記錄,索引等數據。 段 段分為,數據段(Leaf node segment) ,索引段(Non-leaf node segment),回 ...
  • 需要工具: 1、apktool:獲取資源文件,提取圖片文件,佈局文件,還有一些XML的資源文件 2、dex2jar:將APK反編譯成Java源碼(將classes.dex轉化為jar文件) 3、**jd-gui:**查看轉換後的jar文件 1、使用apktool獲得資源文件以及xml文件 1.1、下 ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 1.起因 最近有一個需求,需要使用自定義插件,來對接硬體功能,需要配合對手機的許可權進行判斷和提示,併在對接後對本地文件進行操作,這裡給大家分享下我的碰到的問題,廢話不多說,開搞 2.對接自定義插件,製作自定義基座 manifest.jso ...
  • 在 《JS 模塊化》系列開篇中,曾提到前端技術的發展不斷融入很多後端思想,形成前端的“四個現代化”:工程化、模塊化、規範化、流程化。在該系列文章中已詳細介紹了模塊化的發展及四種模塊化規範。本文簡單聊聊規範化中的 git 規範。 ...
  • 這段時間在開發一個騰訊文檔全品類通用的 HTML 動態服務,為了方便各品類接入的生成與部署,也順應上雲的趨勢,考慮使用 Docker 的方式來固定服務內容,統一進行製品版本的管理。本篇文章就將我在服務 Docker 化的過程中積累起來的優化經驗分享出來,供大家參考。 以一個例子開頭,大部分剛接觸 D ...
  • 1 什麼是流程引擎 流程引擎是一個底層支撐平臺,是為提供流程處理而開發設計的。流程引擎和流程應用,以及應用程式的關係如下圖所示。 常見的支撐場景有:Workflow、BPM、流程編排等。本次分享,主要從BPM流程引擎切入,介紹流程引擎的架構設計方法。 1.1 什麼是流程 簡單來說,流程就是一系列活動 ...
  • 顧名思義,迭代器就是用於迭代操作的對象,其能夠像有序序列一樣迭代獲取集合中對象,並且能夠記錄下當前所在位置,因此也稱游標。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...