Skip to content

Commit f298c38

Browse files
author
songshiyuan 00649746
committed
[opt] add cache to the logic of auth to improve performance in the scene of rbac
1 parent ab888f0 commit f298c38

File tree

3 files changed

+77
-11
lines changed

3 files changed

+77
-11
lines changed

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ require (
7373
)
7474

7575
require (
76+
github.com/form3tech-oss/jwt-go v3.2.3+incompatible
7677
github.com/ghodss/yaml v1.0.0
7778
github.com/go-chassis/go-chassis-extension/protocol/fiber4r v0.0.0-20220825091211-99d5e9810fd7
7879
)
@@ -99,7 +100,6 @@ require (
99100
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 // indirect
100101
github.com/eapache/queue v1.1.0 // indirect
101102
github.com/emicklei/go-restful v2.15.1-0.20220703112237-d9c71e118c95+incompatible // indirect
102-
github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect
103103
github.com/fsnotify/fsnotify v1.5.1 // indirect
104104
github.com/go-chassis/go-restful-swagger20 v1.0.4-0.20220704025524-9243cbee26b7 // indirect
105105
github.com/go-chassis/sc-client v0.6.1-0.20220728072125-dacdd0c834bf // indirect

server/plugin/auth/buildin/buildin.go

+49-5
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,18 @@ package buildin
1919

2020
import (
2121
"context"
22+
"encoding/json"
2223
"errors"
2324
"fmt"
2425
"net/http"
2526
"strings"
27+
"time"
28+
29+
"github.com/form3tech-oss/jwt-go"
30+
rbacmodel "github.com/go-chassis/cari/rbac"
31+
"github.com/go-chassis/go-chassis/v2/security/authr"
32+
"github.com/go-chassis/go-chassis/v2/server/restful"
33+
"github.com/patrickmn/go-cache"
2634

2735
"github.com/apache/servicecomb-service-center/pkg/log"
2836
"github.com/apache/servicecomb-service-center/pkg/plugin"
@@ -32,12 +40,14 @@ import (
3240
"github.com/apache/servicecomb-service-center/server/plugin/auth"
3341
rbacsvc "github.com/apache/servicecomb-service-center/server/service/rbac"
3442
"github.com/apache/servicecomb-service-center/server/service/rbac/token"
35-
rbacmodel "github.com/go-chassis/cari/rbac"
36-
"github.com/go-chassis/go-chassis/v2/security/authr"
37-
"github.com/go-chassis/go-chassis/v2/server/restful"
3843
)
3944

4045
var ErrNoRoles = errors.New("no role found in token")
46+
var tokenCache = cache.New(cacheDefaultExpireTime, cacheDefaultCleanUpTime)
47+
48+
const cacheErrorItemExpTime = 5 * time.Minute
49+
const cacheDefaultExpireTime = 5 * time.Minute
50+
const cacheDefaultCleanUpTime = 10 * time.Minute
4151

4252
func init() {
4353
plugin.RegisterPlugin(plugin.Plugin{Kind: auth.AUTH, Name: "buildin", New: New})
@@ -152,6 +162,15 @@ func (ba *TokenAuthenticator) VerifyToken(req *http.Request) (interface{}, error
152162
if v == "" {
153163
return nil, rbacmodel.NewError(rbacmodel.ErrNoAuthHeader, "")
154164
}
165+
claims, ok := tokenCache.Get(v)
166+
if ok {
167+
switch claimsVal := claims.(type) {
168+
case error:
169+
return nil, claimsVal
170+
default:
171+
return claimsVal, nil
172+
}
173+
}
155174
s := strings.Split(v, " ")
156175
if len(s) != 2 {
157176
return nil, rbacmodel.ErrInvalidHeader
@@ -160,24 +179,49 @@ func (ba *TokenAuthenticator) VerifyToken(req *http.Request) (interface{}, error
160179

161180
claims, err := authr.Authenticate(req.Context(), to)
162181
if err != nil {
182+
SetTokenToCache(tokenCache, v, err)
163183
return nil, err
164184
}
185+
SetTokenToCache(tokenCache, v, claims)
165186
token.WithRequest(req, to)
166187
return claims, nil
167188
}
168189

190+
func SetTokenToCache(tokenCache *cache.Cache, rawToken string, claims interface{}) {
191+
switch claimsVal := claims.(type) {
192+
case error:
193+
tokenCache.Set(rawToken, claimsVal, cacheErrorItemExpTime)
194+
case jwt.MapClaims:
195+
var expr int64
196+
switch exp := claimsVal["exp"].(type) {
197+
case float64:
198+
expr = int64(exp)
199+
case json.Number:
200+
expr, _ = exp.Int64()
201+
default:
202+
expr = time.Now().Add(cacheDefaultExpireTime).Unix()
203+
}
204+
expDur := time.Until(time.Unix(expr, 0))
205+
if expDur > 0 {
206+
tokenCache.Set(rawToken, claimsVal, expDur)
207+
}
208+
default:
209+
return
210+
}
211+
}
212+
169213
// this method decouple business code and perm checks
170214
func checkPerm(roleList []string, req *http.Request) ([]map[string]string, error) {
171215
hasAdmin, normalRoles := filterRoles(roleList)
172216
if hasAdmin {
173217
return nil, nil
174218
}
175-
//todo fast check for dev role
219+
// todo fast check for dev role
176220
targetResource := FromRequest(req)
177221
if targetResource == nil {
178222
return nil, errors.New("no valid resouce scope")
179223
}
180-
//TODO add project
224+
// TODO add project
181225
project := req.URL.Query().Get(":project")
182226
return rbacsvc.Allow(req.Context(), project, normalRoles, targetResource)
183227
}

server/plugin/auth/buildin/buildin_test.go

+27-5
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,18 @@ package buildin_test
2020
// initialize
2121
import (
2222
"context"
23+
"errors"
2324
"net/http"
2425
"net/http/httptest"
2526
"os"
2627
"testing"
28+
"time"
29+
30+
"github.com/form3tech-oss/jwt-go"
31+
"github.com/patrickmn/go-cache"
2732

2833
_ "github.com/apache/servicecomb-service-center/test"
2934

30-
"github.com/apache/servicecomb-service-center/pkg/rest"
31-
"github.com/apache/servicecomb-service-center/pkg/util"
32-
"github.com/apache/servicecomb-service-center/server/config"
33-
"github.com/apache/servicecomb-service-center/server/plugin/auth/buildin"
34-
rbacsvc "github.com/apache/servicecomb-service-center/server/service/rbac"
3535
beego "github.com/beego/beego/v2/server/web"
3636
"github.com/go-chassis/cari/pkg/errsvc"
3737
carirbac "github.com/go-chassis/cari/rbac"
@@ -41,6 +41,12 @@ import (
4141
"github.com/go-chassis/go-chassis/v2/security/secret"
4242
"github.com/go-chassis/go-chassis/v2/server/restful"
4343
"github.com/stretchr/testify/assert"
44+
45+
"github.com/apache/servicecomb-service-center/pkg/rest"
46+
"github.com/apache/servicecomb-service-center/pkg/util"
47+
"github.com/apache/servicecomb-service-center/server/config"
48+
"github.com/apache/servicecomb-service-center/server/plugin/auth/buildin"
49+
rbacsvc "github.com/apache/servicecomb-service-center/server/service/rbac"
4450
)
4551

4652
func init() {
@@ -175,3 +181,19 @@ func TestTokenAuthenticator_Identify(t *testing.T) {
175181
}
176182
})
177183
}
184+
185+
func TestSetTokenToCache(t *testing.T) {
186+
tokenCache1 := cache.New(5*time.Minute, 10*time.Minute)
187+
rawToken1 := "**1"
188+
rawToken2 := "**2"
189+
deleta, _ := time.ParseDuration("10m")
190+
claims := &jwt.MapClaims{"exp": float64(time.Now().Add(deleta).Unix())}
191+
t.Run("test Cache", func(t *testing.T) {
192+
buildin.SetTokenToCache(tokenCache1, rawToken1, claims)
193+
buildin.SetTokenToCache(tokenCache1, rawToken2, errors.New("bad token"))
194+
res1, _ := tokenCache1.Get(rawToken1)
195+
res2, _ := tokenCache1.Get(rawToken2)
196+
assert.NotNil(t, res1)
197+
assert.NotNil(t, res2)
198+
})
199+
}

0 commit comments

Comments
 (0)