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  }