github.com/infraboard/keyauth@v0.8.1/common/interceptor/http/http.go (about) 1 package auther 2 3 import ( 4 "context" 5 "net/http" 6 7 "github.com/rs/xid" 8 9 "github.com/infraboard/mcube/app" 10 "github.com/infraboard/mcube/exception" 11 "github.com/infraboard/mcube/logger" 12 "github.com/infraboard/mcube/logger/zap" 13 httpb "github.com/infraboard/mcube/pb/http" 14 15 "github.com/infraboard/keyauth/apps/token" 16 "github.com/infraboard/keyauth/apps/user/types" 17 "github.com/infraboard/keyauth/common/header" 18 ) 19 20 // NewInternalAuther 内部使用的auther 21 func NewHTTPAuther() *HTTPAuther { 22 return &HTTPAuther{ 23 l: zap.L().Named("Http Interceptor"), 24 token: app.GetGrpcApp(token.AppName).(token.ServiceServer), 25 } 26 } 27 28 // internal todo 29 type HTTPAuther struct { 30 l logger.Logger 31 token token.ServiceServer 32 } 33 34 func (a *HTTPAuther) Auth(r *http.Request, entry httpb.Entry) ( 35 authInfo interface{}, err error) { 36 var tk *token.Token 37 38 // 从请求中获取access token 39 acessToken := r.Header.Get(header.OAuthTokenHeader) 40 41 if entry.AuthEnable { 42 ctx := r.Context() 43 44 // 校验身份 45 tk, err = a.ValidateIdentity(ctx, acessToken) 46 if err != nil { 47 return nil, err 48 } 49 50 // namesapce检查 51 if entry.RequiredNamespace && tk.NamespaceId == "" { 52 return nil, exception.NewBadRequest("namespace required!") 53 } 54 55 // 权限检查 56 err = a.ValidatePermission(ctx, tk, entry) 57 if err != nil { 58 return nil, err 59 } 60 } 61 62 // 设置RequestID 63 if r.Header.Get(header.RequestIdHeader) == "" { 64 r.Header.Set(header.RequestIdHeader, xid.New().String()) 65 } 66 67 return tk, nil 68 } 69 70 func (a *HTTPAuther) ValidateIdentity(ctx context.Context, accessToken string) (*token.Token, error) { 71 a.l.Debug("start token identity check ...") 72 73 if accessToken == "" { 74 return nil, exception.NewBadRequest("token required") 75 } 76 77 req := token.NewValidateTokenRequest() 78 req.AccessToken = accessToken 79 tk, err := a.token.ValidateToken(ctx, req) 80 if err != nil { 81 return nil, err 82 } 83 84 a.l.Debugf("token check ok, username: %s", tk.Account) 85 return tk, nil 86 } 87 88 func (a *HTTPAuther) ValidatePermission(ctx context.Context, tk *token.Token, e httpb.Entry) error { 89 if tk == nil { 90 return exception.NewUnauthorized("validate permission need token") 91 } 92 93 // 如果是不做权限校验, 超级管理员直接放行 94 if tk.UserType.IsIn(types.UserType_SUPPER) { 95 a.l.Debugf("[%s] supper admin skip permission check!", tk.Account) 96 return nil 97 } 98 99 // 检查是否是允许的类型 100 if len(e.Allow) > 0 { 101 a.l.Debugf("[%s] start check permission to keyauth ...", tk.Account) 102 if !e.IsAllow(tk.UserType) { 103 return exception.NewPermissionDeny("no permission, allow: %s, but current: %s", e.Allow, tk.UserType) 104 } 105 a.l.Debugf("[%s] permission check passed", tk.Account) 106 } 107 108 return nil 109 } 110 111 // func (a *HTTPAuther) ResponseHook(w http.ResponseWriter, r *http.Request, entry httpb.Entry) { 112 // ctx := httpctx.GetContext(r) 113 // tk := ctx.AuthInfo.(*token.Token) 114 115 // // 审计日志 116 // od := newOperateEventData(&entry, tk) 117 // hd := newEventHeaderFromHTTP(r) 118 // if entry.AuditLog { 119 // if err := SendOperateEvent(r.URL.String(), nil, hd, od); err != nil { 120 // a.l.Errorf("send operate event error, %s", err) 121 // } 122 // } 123 // } 124 125 // SetLogger todo 126 func (a *HTTPAuther) SetLogger(l logger.Logger) { 127 a.l = l 128 }