osg VerifyJWT 추가
This commit is contained in:
@ -9,6 +9,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"slices"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
@ -155,6 +156,49 @@ func (c *Client) MakeJWT(subject string, role string, ttl time.Duration) string
|
||||
return encoded + "." + string(sigenc)
|
||||
}
|
||||
|
||||
func (c *Client) VerifyJWT(token string) (subject string, role string) {
|
||||
dot := strings.LastIndex(token, ".")
|
||||
if dot < 0 {
|
||||
return
|
||||
}
|
||||
|
||||
encoded := token[:dot]
|
||||
sigenc := token[dot+1:]
|
||||
signature := make([]byte, encoding.DecodedLen(len(sigenc)))
|
||||
encoding.Decode(signature, []byte(sigenc))
|
||||
|
||||
mac := hmac.New(sha256.New, c.signingKey)
|
||||
mac.Write([]byte(encoded))
|
||||
calsig := mac.Sum(nil)
|
||||
if slices.Compare(calsig, signature) != 0 {
|
||||
return
|
||||
}
|
||||
|
||||
_, payload, ok := strings.Cut(encoded, ".")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
srcjson, err := encoding.DecodeString(payload)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var src struct {
|
||||
Exp int64 `json:"exp"`
|
||||
Sub string `json:"sub"`
|
||||
Roles string `json:"roles"`
|
||||
}
|
||||
if json.Unmarshal([]byte(srcjson), &src) != nil {
|
||||
return
|
||||
}
|
||||
if src.Exp < time.Now().Unix() {
|
||||
return
|
||||
}
|
||||
|
||||
return src.Sub, src.Roles
|
||||
}
|
||||
|
||||
func NewClient(cfg Config) (Client, error) {
|
||||
if len(cfg.Addresses) == 0 {
|
||||
return Client{}, nil
|
||||
|
||||
@ -1,7 +1,11 @@
|
||||
package opensearch
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
func TestNewClient(t *testing.T) {
|
||||
@ -31,3 +35,44 @@ func TestNewClient(t *testing.T) {
|
||||
// time.Sleep(time.Second)
|
||||
// }
|
||||
}
|
||||
|
||||
func TestClient_MakeJWT(t *testing.T) {
|
||||
sk := "UGdiOTdLVjFBTWtndTRNRiZmVjdwMDdCRW1lSSUxTnA="
|
||||
dst := make([]byte, len(sk)*2)
|
||||
dstlen, _ := base64.StdEncoding.Decode(dst, []byte(sk))
|
||||
signingKey := dst[:dstlen]
|
||||
uid := primitive.NewObjectID().Hex()
|
||||
|
||||
type args struct {
|
||||
subject string
|
||||
role string
|
||||
ttl time.Duration
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
c *Client
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
// TODO: Add test cases.
|
||||
{
|
||||
c: &Client{
|
||||
signingKey: signingKey,
|
||||
},
|
||||
args: args{
|
||||
subject: uid,
|
||||
role: "ds_client",
|
||||
ttl: time.Minute,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := tt.c.MakeJWT(tt.args.subject, tt.args.role, tt.args.ttl)
|
||||
subj, role := tt.c.VerifyJWT(got)
|
||||
if subj != tt.args.subject || role != tt.args.role {
|
||||
t.Errorf("Client.MakeJWT() = %v, %v, want %v, %v", subj, role, tt.args.subject, tt.args.role)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user