如何使用阿里云FC的JWT网关统一拦截

使用golang签发JWT

0x01 生成RSA密钥对

https://mkjwk.org/?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"keys": [
{
"p": "7Ks-LNbE4bhnec54YSgnlngwwIm3dOg3oiHvvkJ0yrEt5oir30bvQo_NjJm94Wz35T3zvnCdr8H5dpV88MWoRIe-PhJ0HWA05giDR0G3bD5GkFqtq31hOp_2AOt_nbWSDZPeoS5GwyATAOS4rKSh1ZDbURrgXGn8WKNNcvjBW18",
"kty": "RSA",
"q": "paMmlRdEJF0FPTCDl3u-E6c2bnGJ8Api2zty39P1oq6PYzea3TpDb61qj53auaPh_whHAlOGAhpHXWzZ2aLcwI0f80R-2DPJX6FRbIZ9vk5dR3tSaSTLG8n-Dyj7t7A6S0tFT48dshmw3NiPiRrDZPD1qOw6ckY-e0JqbyM2N7k",
"d": "W86oODM7BiizrzKUKlL5RQv2zD_EiA86O8uQ1SvXLmBaoBmO6w9QNgGdT8azfCLEmTN5Hs1vFF7fJWaFp2cB18xKtOgCRjiuYJiN2A4FWmtpi390GgkYKvvTxoUDb3J_Eb4nikxp7mGvFKaDhX4NQ52pTGLwYgeLi2IIqYLHpaMqck2vdP1SahKsm81e0rZ8hYSi5VJsfpUnOm6Nxb277kPAh019cV3AaWLyMnFLSowOIiIZLNA4K3aetA5BpQnhxAzGiAI1f1ERfK2asLxQcYE_fabMzBz45od_yYNjmEauQgl8Wy42UWUZdwfU8512qwr_7dyM4M1ce6cWwl1hwQ",
"e": "AQAB",
"qi": "xgtaScAqZ8DEKSCfHDecDo3KLxsa5JbWBUzevu55o9zbqol8C0p_QUCSlxyTIAA5e6vcPXXutToH7_DqPBHpO-xozNTV1Z7Hhmmq2OQIpiaTf76uCmLam6ARSdIuE0JrYEAOxo0cMXaikO2NA_4LDV6BQlnh4Jt3kua2YoQVFdY",
"dp": "pCuBfK8acY1uUgNUY-jr1SfYgabGWNVAyjoKSQtmYrgXJASIXOCi1aRVLIP1QGtLZnzcGK2b5LCEsKqvuYES4T7cS8iXPU1gRHWBQyul5fMpFbehIwVdLcKKbkbuBmNORhbd5ybntTEJnaQLKs8k57WNPSyMl-55Oq9E6Uz_K7c",
"alg": "RS256",
"dq": "ka0PFtsSlES3gdx0L7umLZTHu5Th8xq_XP9JBfBePgj2lRVnf6BphQPpD4yOvOyUq_90rGgXGSxRjapZYx7otfSooASi5rWNKy0u9prGZqR3R5H_pfe1JqidaGnsEN7ONkBqIhHF1UjhEyrn-nZuWQ3PkRTKRozfEPsVrs8yNQk",
"n": "mSEzxr1h3oJsNK9CC5DLOd01CT4Ol9uHdc8I8Z5ZxP6FYnXybRS9crUlxZjENTSstTsLP0se8k3yNyFnhyh7NcCVSW6tS8eHcuWxqesvq0Dxyhyc2LUWkdAXXb9heOKD2HkWznu24-dHAZL18L0Dr31cWTWWRpLQP62RhfOM3S43DJb2ifcJn8Pa7LO_GPJnTTNFquQbVMLRfOepZmuwZ1I4cLLD5gzJ5azWBGHjaTHTsAOGTbndxYUYxreROaiImW6kJQvo5WzoUsES8nJQTEeXt89qANAxAz-af4KV-a9OKkX99QzMKd0qDDQ_NEvIE0Z0SW8OKAxRE4f_kWZwpw"
}
]
}

0x02 golang生成jwt

这里使用embed加载了jwtkey的文件,文件内容就是

1
2
3
4
5
{
"alg": "RS256",
....
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package main

import (
"crypto/rsa"
_ "embed"
"encoding/base64"
"encoding/json"
"fmt"
"math/big"
"time"

"github.com/dgrijalva/jwt-go"
)

type PublicKey struct {
Kty string `json:"kty"`
E string `json:"e"`
N string `json:"n"`
}

type PrivateKey struct {
PublicKey
D string `json:"d"`
Qi string `json:"qi"`
Q string `json:"q"`
Dp string `json:"dp"`
Dq string `json:"dq"`
}

//go:embed jwt.key
var keyJSON string

func genJwt() {
// 解析密钥JSON

var privateKey PrivateKey
err := json.Unmarshal([]byte(keyJSON), &privateKey)
if err != nil {
fmt.Printf("Failed to parse key JSON: %v\n", err)
return
}

// 解码Base64编码的密钥
nBytes, err := base64.RawURLEncoding.DecodeString(privateKey.N)
if err != nil {
fmt.Printf("Failed to decode modulus: %v\n", err)
return
}
dBytes, err := base64.RawURLEncoding.DecodeString(privateKey.D)
if err != nil {
fmt.Printf("Failed to decode private exponent: %v\n", err)
return
}
eBytes, err := base64.RawURLEncoding.DecodeString(privateKey.E)
if err != nil {
fmt.Printf("Failed to decode public exponent: %v\n", err)
return
}

// 构建RSA私钥
rsaPrivateKey := &rsa.PrivateKey{
PublicKey: rsa.PublicKey{
N: rsaDecode(nBytes),
E: int(extractBigEndianValue(eBytes)),
},
D: rsaDecode(dBytes),
Primes: []*big.Int{
rsaDecode([]byte(privateKey.Q)),
},
Precomputed: rsa.PrecomputedValues{},
}

// 创建JWT声明
claims := jwt.StandardClaims{
Subject: "user123",
ExpiresAt: time.Now().Add(time.Minute * 10).Unix(),
}

// 签发JWT令牌
token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)
signedToken, err := token.SignedString(rsaPrivateKey)
if err != nil {
fmt.Printf("Failed to sign token: %v\n", err)
return
}

fmt.Println(signedToken)
}

// 辅助函数:将字节数据转换为big.Int类型
func rsaDecode(data []byte) *big.Int {
var result big.Int
result.SetBytes(data)
return &result
}

// 辅助函数:从字节切片中提取大端值
func extractBigEndianValue(data []byte) uint64 {
value := uint64(0)
for _, b := range data {
value = (value << 8) + uint64(b)
}
return value
}

计算得到jwt,

设置阿里云FC的JWT认证拦截

接入

作者

舰长胡椒

发布于

2023-07-29

更新于

2023-10-13

许可协议

评论