feat: 实现 OIDC 服务端会话与请求刷新
使用 AES-256-GCM 保存认证中心令牌,并以随机 Cookie 哈希关联 PostgreSQL 会话。加入闲置与绝对期限、Refresh Token 轮换以及多实例刷新锁。
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
package oidcsession
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCipherEncryptsTokenBundleAndAuthenticatesContext(t *testing.T) {
|
||||
key := bytes.Repeat([]byte{0x42}, 32)
|
||||
cipher, err := NewCipher(key)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
bundle := TokenBundle{AccessToken: "plain-access", RefreshToken: "plain-refresh", IDToken: "plain-id"}
|
||||
encrypted, err := cipher.EncryptBundle(bundle, "session-id", "gateway-user-id")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if strings.Contains(string(encrypted), "plain-") {
|
||||
t.Fatal("token bundle was stored in plaintext")
|
||||
}
|
||||
decoded, err := cipher.DecryptBundle(encrypted, "session-id", "gateway-user-id")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if decoded != bundle {
|
||||
t.Fatalf("decoded bundle = %#v", decoded)
|
||||
}
|
||||
if _, err := cipher.DecryptBundle(encrypted, "another-session", "gateway-user-id"); err == nil {
|
||||
t.Fatal("ciphertext was accepted with different authenticated context")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCipherRequiresIndependentAES256Key(t *testing.T) {
|
||||
if _, err := NewCipher(make([]byte, 31)); err == nil {
|
||||
t.Fatal("31-byte key was accepted")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user