Skip to content

Commit a946c7c

Browse files
committed
feat: none
1 parent 72298f8 commit a946c7c

25 files changed

+1808
-305
lines changed

auth/api.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ type AuthChecker interface {
6060
Initialize(options *Config, cacheMgn *cache.NamingCache) error
6161

6262
// VerifyToken 验证令牌
63-
VerifyToken(preCtx *model.AcquireContext) error
63+
VerifyCredential(preCtx *model.AcquireContext) error
6464

6565
// CheckPermission 执行检查动作判断是否有权限,并且将 RequestContext 进行插入一些新的数据
6666
CheckPermission(preCtx *model.AcquireContext) (bool, error)

auth/defaultauth/auth_mgn_core.go

Lines changed: 104 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,11 @@ import (
2222
"errors"
2323
"strings"
2424

25-
"go.uber.org/zap"
26-
2725
api "github.com/polarismesh/polaris-server/common/api/v1"
2826
"github.com/polarismesh/polaris-server/common/log"
2927
"github.com/polarismesh/polaris-server/common/model"
3028
"github.com/polarismesh/polaris-server/common/utils"
29+
"go.uber.org/zap"
3130
)
3231

3332
// IsOpenAuth 返回是否开启了操作鉴权
@@ -44,44 +43,43 @@ func (authMgn *defaultAuthChecker) IsOpenAuth() bool {
4443
// step 3. 拉取token对应的操作者相关信息,注入到请求上下文中
4544
// step 4. 进行权限检查
4645
func (authMgn *defaultAuthChecker) CheckPermission(authCtx *model.AcquireContext) (bool, error) {
47-
reqId := utils.ParseRequestID(authCtx.GetRequestContext())
48-
4946
if !authMgn.IsOpenAuth() {
5047
return true, nil
5148
}
5249

53-
if err := authMgn.VerifyToken(authCtx); err != nil {
54-
if errors.Is(err, model.ErrorTokenDisabled) && authCtx.GetOperation() == model.Read {
55-
// 当前读操作不处理
56-
return true, nil
57-
}
50+
reqId := utils.ParseRequestID(authCtx.GetRequestContext())
51+
if err := authMgn.VerifyCredential(authCtx); err != nil {
5852
return false, err
5953
}
6054

61-
// 开启鉴权之后,读操作需要一些鉴权上下文的信息,因此必须要先走完 verifytoken 才可以结束
6255
if authCtx.GetOperation() == model.Read {
6356
return true, nil
6457
}
6558

66-
tokenInfo := authCtx.GetAttachment()[model.TokenDetailInfoKey].(TokenInfo)
67-
strategies, err := authMgn.findStrategies(tokenInfo)
68-
// 如果访问的资源,其 owner 找不到对应的用户,则认为是可以被随意操作的资源
69-
noResourceNeedCheck := authMgn.removeNoStrategyResources(authCtx)
59+
operatorInfo := authCtx.GetAttachment(model.TokenDetailInfoKey).(OperatorInfo)
60+
if operatorInfo.Disable {
61+
return false, model.ErrorTokenDisabled
62+
}
7063

64+
strategies, err := authMgn.findStrategies(operatorInfo)
7165
if err != nil {
7266
log.AuthScope().Error("[Auth][Server] find strategies when check permission", utils.ZapRequestID(reqId),
73-
zap.Error(err), zap.String("token", tokenInfo.String()))
67+
zap.Error(err), zap.Any("token", operatorInfo.String()))
7468
return false, err
7569
}
7670

77-
authCtx.GetAttachment()[model.OperatorLinkStrategy] = strategies
71+
authCtx.SetAttachment(model.OperatorLinkStrategy, strategies)
7872

73+
noResourceNeedCheck := authMgn.removeNoStrategyResources(authCtx)
7974
if !noResourceNeedCheck && len(strategies) == 0 {
8075
log.AuthScope().Error("[Auth][Server]", utils.ZapRequestID(reqId),
8176
zap.String("msg", "need check resource is not empty, but strategies is empty"))
82-
return false, errors.New(api.Code2Info(api.NotAllowedAccess))
77+
return false, errors.New("need check resource is not empty, but strategies is empty")
8378
}
8479

80+
log.AuthScope().Info("[Auth][Server] check permission args", zap.Any("resources", authCtx.GetAccessResources()),
81+
zap.Any("strategies", strategies))
82+
8583
ok, err := authMgn.authPlugin.CheckPermission(authCtx, strategies)
8684
if err != nil {
8785
log.AuthScope().Error("[Auth][Server] check permission args", utils.ZapRequestID(reqId),
@@ -94,97 +92,137 @@ func (authMgn *defaultAuthChecker) CheckPermission(authCtx *model.AcquireContext
9492
return ok, err
9593
}
9694

97-
// verifyToken 对 token 进行检查验证,并将 verify 过程中解析出的数据注入到 model.AcquireContext 中
95+
func canDowngradeAnonymous(authCtx *model.AcquireContext, err error) bool {
96+
if authCtx.GetModule() == model.AuthModule {
97+
return false
98+
}
99+
100+
if AuthOption.Strict {
101+
return false
102+
}
103+
104+
if errors.Is(err, model.ErrorTokenInvalid) {
105+
return true
106+
}
107+
if errors.Is(err, model.ErrorTokenNotExist) {
108+
return true
109+
}
110+
111+
return false
112+
}
113+
114+
// VerifyCredential 对 token 进行检查验证,并将 verify 过程中解析出的数据注入到 model.AcquireContext 中
98115
// step 1. 首先对 token 进行解析,获取相关的数据信息,注入到整个的 AcquireContext 中
99116
// step 2. 最后对 token 进行一些验证步骤的执行
100-
func (authMgn *defaultAuthChecker) VerifyToken(authCtx *model.AcquireContext) error {
117+
// step 3. 兜底措施:如果开启了鉴权的非严格模式,则根据错误的类型,判断是否转为匿名用户进行访问
118+
// - 如果不是访问权限控制相关模块(用户、用户组、权限策略),不得转为匿名用户
119+
func (authMgn *defaultAuthChecker) VerifyCredential(authCtx *model.AcquireContext) error {
101120
if !authMgn.IsOpenAuth() && authCtx.GetModule() != model.AuthModule {
102121
return nil
103122
}
104123

105-
tokenInfo, err := authMgn.DecodeToken(authCtx.GetToken())
106-
if err != nil {
107-
log.AuthScope().Error("[Auth][Server] decode token", utils.ZapRequestIDByCtx(authCtx.GetRequestContext()),
108-
zap.Error(err))
109-
return err
110-
}
124+
reqId := utils.ParseRequestID(authCtx.GetRequestContext())
111125

112-
ownerId, isOwner, err := authMgn.checkToken(&tokenInfo)
113-
if err != nil {
114-
log.AuthScope().Error("[Auth][Server] check token", utils.ZapRequestIDByCtx(authCtx.GetRequestContext()),
115-
zap.Error(err))
116-
return err
126+
checkErr := func() error {
127+
operator, err := authMgn.decodeToken(authCtx.GetToken())
128+
if err != nil {
129+
log.AuthScope().Error("[Auth][Server] decode token", zap.Error(err))
130+
return model.ErrorTokenInvalid
131+
}
132+
133+
ownerId, isOwner, err := authMgn.checkToken(&operator)
134+
if err != nil {
135+
log.AuthScope().Error("[Auth][Server] check token", zap.Error(err))
136+
return err
137+
}
138+
139+
operator.OwnerID = ownerId
140+
ctx := authCtx.GetRequestContext()
141+
ctx = context.WithValue(ctx, utils.ContextIsOwnerKey, isOwner)
142+
ctx = context.WithValue(ctx, utils.ContextUserIDKey, operator.OperatorID)
143+
ctx = context.WithValue(ctx, utils.ContextOwnerIDKey, ownerId)
144+
authCtx.SetRequestContext(ctx)
145+
authMgn.parseOperatorInfo(operator, authCtx)
146+
if operator.Disable {
147+
log.AuthScope().Warn("[Auth][Server] token already disabled", utils.ZapRequestID(reqId),
148+
zap.Any("token", operator.String()))
149+
}
150+
return nil
151+
}()
152+
153+
if checkErr != nil {
154+
if !canDowngradeAnonymous(authCtx, checkErr) {
155+
return checkErr
156+
}
157+
log.AuthScope().Warn("[Auth][Server] parse operator info, downgrade to anonymous", utils.ZapRequestID(reqId),
158+
zap.Error(checkErr))
159+
// 操作者信息解析失败,降级为匿名用户
160+
authCtx.SetAttachment(model.TokenDetailInfoKey, newAnonymous())
117161
}
118162

163+
return nil
164+
}
165+
166+
func (authMgn *defaultAuthChecker) parseOperatorInfo(operator OperatorInfo, authCtx *model.AcquireContext) {
167+
119168
ctx := authCtx.GetRequestContext()
120169

121-
if tokenInfo.IsUserToken {
122-
user := authMgn.Cache().User().GetUserByID(tokenInfo.OperatorID)
123-
tokenInfo.Role = user.Type
170+
if operator.IsUserToken {
171+
user := authMgn.Cache().User().GetUserByID(operator.OperatorID)
172+
operator.Role = user.Type
124173
ctx = context.WithValue(ctx, utils.ContextUserRoleIDKey, user.Type)
125174
}
126175

127-
ctx = context.WithValue(ctx, utils.ContextIsOwnerKey, isOwner)
128-
ctx = context.WithValue(ctx, utils.ContextUserIDKey, tokenInfo.OperatorID)
129-
ctx = context.WithValue(ctx, utils.ContextOwnerIDKey, ownerId)
130-
131-
authCtx.GetAttachment()[model.OperatorRoleKey] = tokenInfo.Role
132-
authCtx.GetAttachment()[model.OperatorPrincipalType] = func() model.PrincipalType {
133-
if tokenInfo.IsUserToken {
176+
authCtx.SetAttachment(model.OperatorRoleKey, operator.Role)
177+
authCtx.SetAttachment(model.OperatorPrincipalType, func() model.PrincipalType {
178+
if operator.IsUserToken {
134179
return model.PrincipalUser
135180
}
136181
return model.PrincipalGroup
137-
}()
138-
authCtx.GetAttachment()[model.OperatorIDKey] = tokenInfo.OperatorID
139-
authCtx.GetAttachment()[model.OperatorOwnerKey] = ownerId
140-
authCtx.GetAttachment()[model.TokenDetailInfoKey] = tokenInfo
182+
}())
183+
authCtx.SetAttachment(model.OperatorIDKey, operator.OperatorID)
184+
authCtx.SetAttachment(model.OperatorOwnerKey, operator)
185+
authCtx.SetAttachment(model.TokenDetailInfoKey, operator)
141186

142187
authCtx.SetRequestContext(ctx)
143-
144-
if tokenInfo.Disable {
145-
log.AuthScope().Error("[Auth][Server] token already disabled",
146-
utils.ZapRequestIDByCtx(authCtx.GetRequestContext()), zap.String("token", tokenInfo.String()))
147-
return model.ErrorTokenDisabled
148-
}
149-
return nil
150188
}
151189

152-
// DecodeToken 解析 token 信息,如果 t == "",直接返回一个空对象
153-
func (authMgn *defaultAuthChecker) DecodeToken(t string) (TokenInfo, error) {
190+
// decodeToken 解析 token 信息,如果 t == "",直接返回一个空对象
191+
func (authMgn *defaultAuthChecker) decodeToken(t string) (OperatorInfo, error) {
154192
if t == "" {
155-
return TokenInfo{}, nil
193+
return OperatorInfo{}, model.ErrorTokenInvalid
156194
}
157195

158196
ret, err := decryptMessage([]byte(AuthOption.Salt), t)
159197
if err != nil {
160-
return TokenInfo{}, err
198+
return OperatorInfo{}, err
161199
}
162200
tokenDetails := strings.Split(ret, TokenSplit)
163201
if len(tokenDetails) != 2 {
164-
return TokenInfo{}, model.ErrorTokenInvalid
202+
return OperatorInfo{}, model.ErrorTokenInvalid
165203
}
166204

167205
detail := strings.Split(tokenDetails[1], "/")
168206
if len(detail) != 2 {
169-
return TokenInfo{}, model.ErrorTokenInvalid
207+
return OperatorInfo{}, model.ErrorTokenInvalid
170208
}
171209

172-
tokenInfo := TokenInfo{
210+
tokenInfo := OperatorInfo{
173211
Origin: t,
174212
IsUserToken: detail[0] == model.TokenForUser,
175213
OperatorID: detail[1],
176214
Role: model.UnknownUserRole,
177215
}
178216

179-
log.AuthScope().Info("[Auth][Server] token detail", zap.String("info", tokenInfo.String()))
217+
log.AuthScope().Info("[Auth][Server] token detail", zap.Any("info", tokenInfo.String()))
180218

181219
return tokenInfo, nil
182220
}
183221

184222
// checkToken 对 token 进行检查,如果 token 是一个空,直接返回默认值,但是不返回错误
185223
// return {owner-id} {is-owner} {error}
186-
func (authMgn *defaultAuthChecker) checkToken(tokenInfo *TokenInfo) (string, bool, error) {
187-
if tokenInfo.IsEmpty() {
224+
func (authMgn *defaultAuthChecker) checkToken(tokenInfo *OperatorInfo) (string, bool, error) {
225+
if IsEmptyOperator(*tokenInfo) {
188226
return "", false, nil
189227
}
190228

@@ -244,12 +282,12 @@ func (authMgn *defaultAuthChecker) findStrategiesByUserID(userId string) []*mode
244282
}
245283

246284
// findStrategies Inquire about TOKEN information, the actual all-associated authentication strategy
247-
func (authMgn *defaultAuthChecker) findStrategies(tokenInfo TokenInfo) ([]*model.StrategyDetail, error) {
285+
func (authMgn *defaultAuthChecker) findStrategies(tokenInfo OperatorInfo) ([]*model.StrategyDetail, error) {
248286
var (
249287
strategies []*model.StrategyDetail
250288
)
251289

252-
if tokenInfo.IsEmpty() {
290+
if IsEmptyOperator(tokenInfo) {
253291
return make([]*model.StrategyDetail, 0), nil
254292
}
255293

@@ -317,7 +355,7 @@ func (authMgn *defaultAuthChecker) removeNoStrategyResources(authCtx *model.Acqu
317355
}
318356

319357
if authCtx.GetModule() == model.ConfigModule {
320-
// 检查配置空间
358+
// 检查配置
321359
cfgRes := resources[api.ResourceType_ConfigGroups]
322360
newCfgRes := make([]model.ResourceEntry, 0)
323361
for index := range cfgRes {
@@ -329,13 +367,13 @@ func (authMgn *defaultAuthChecker) removeNoStrategyResources(authCtx *model.Acqu
329367
newAccessRes[api.ResourceType_ConfigGroups] = newCfgRes
330368
}
331369

332-
log.AuthScope().Info("[Auth][Server] remove no link strategy resource", utils.ZapRequestID(reqId),
370+
log.AuthScope().Info("[Auth][Server] remove no link strategy final result", utils.ZapRequestID(reqId),
333371
zap.Any("resource", newAccessRes))
334372

335373
authCtx.SetAccessResources(newAccessRes)
336374
noResourceNeedCheck := authCtx.IsAccessResourceEmpty()
337375
if noResourceNeedCheck {
338-
log.AuthScope().Info("[Auth][Server]", utils.ZapRequestID(reqId),
376+
log.AuthScope().Debug("[Auth][Server]", utils.ZapRequestID(reqId),
339377
zap.String("msg", "need check permission resource is empty"))
340378
}
341379

0 commit comments

Comments
 (0)