mirror of
https://github.com/eolinker/apinto
synced 2025-12-24 13:28:15 +08:00
add para hmac
This commit is contained in:
22
application/auth/para-hmac/config.go
Normal file
22
application/auth/para-hmac/config.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package para_hmac
|
||||
|
||||
import "github.com/eolinker/apinto/application"
|
||||
|
||||
type Config struct {
|
||||
application.Auth
|
||||
Users []*User `json:"users" label:"用户列表"`
|
||||
}
|
||||
|
||||
type User struct {
|
||||
Pattern Pattern `json:"pattern" label:"用户信息"`
|
||||
application.User
|
||||
}
|
||||
|
||||
type Pattern struct {
|
||||
AppID string `json:"app_id"`
|
||||
AppKey string `json:"app_key"`
|
||||
}
|
||||
|
||||
func (u *User) Username() string {
|
||||
return u.Pattern.AppID
|
||||
}
|
||||
95
application/auth/para-hmac/executor.go
Normal file
95
application/auth/para-hmac/executor.go
Normal file
@@ -0,0 +1,95 @@
|
||||
package para_hmac
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
|
||||
"github.com/eolinker/apinto/application"
|
||||
)
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
http_service "github.com/eolinker/eosc/eocontext/http-context"
|
||||
)
|
||||
|
||||
var _ application.IAuth = (*executor)(nil)
|
||||
|
||||
type executor struct {
|
||||
id string
|
||||
tokenName string
|
||||
position string
|
||||
users application.IUserManager
|
||||
}
|
||||
|
||||
func (a *executor) GetUser(ctx http_service.IHttpContext) (*application.UserInfo, bool) {
|
||||
token, has := application.GetToken(ctx, a.tokenName, a.position)
|
||||
if !has || token == "" {
|
||||
return nil, false
|
||||
}
|
||||
appId := ctx.Request().Header().GetHeader("X-App-Id")
|
||||
if appId == "" {
|
||||
return nil, false
|
||||
}
|
||||
user, has := a.users.Get(appId)
|
||||
if !has {
|
||||
return nil, false
|
||||
}
|
||||
sequenceNo := ctx.Request().Header().GetHeader("X-Sequence-No")
|
||||
timestamp := ctx.Request().Header().GetHeader("X-Timestamp")
|
||||
body, _ := ctx.Request().Body().RawBody()
|
||||
signText := ctx.Request().Header().GetHeader("X-Signature")
|
||||
verifySign := sign(appId, user.Value, timestamp, sequenceNo, string(body))
|
||||
escapeSign := url.QueryEscape(verifySign)
|
||||
if verifySign == signText || escapeSign == signText {
|
||||
return user, true
|
||||
}
|
||||
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (a *executor) ID() string {
|
||||
return a.id
|
||||
}
|
||||
|
||||
func (a *executor) Driver() string {
|
||||
return driverName
|
||||
}
|
||||
|
||||
func (a *executor) Check(appID string, users []application.ITransformConfig) error {
|
||||
us := make([]application.IUser, 0, len(users))
|
||||
for _, u := range users {
|
||||
v, ok := u.Config().(*User)
|
||||
if !ok {
|
||||
return fmt.Errorf("%s check error: invalid config type", driverName)
|
||||
}
|
||||
us = append(us, v)
|
||||
}
|
||||
return a.users.Check(appID, driverName, us)
|
||||
}
|
||||
|
||||
func (a *executor) Set(app application.IApp, users []application.ITransformConfig) {
|
||||
infos := make([]*application.UserInfo, 0, len(users))
|
||||
for _, u := range users {
|
||||
v, _ := u.Config().(*User)
|
||||
|
||||
infos = append(infos, &application.UserInfo{
|
||||
Name: v.Username(),
|
||||
Value: v.Pattern.AppKey,
|
||||
Expire: v.Expire,
|
||||
Labels: v.Labels,
|
||||
HideCredential: v.HideCredential,
|
||||
App: app,
|
||||
TokenName: a.tokenName,
|
||||
Position: a.position,
|
||||
})
|
||||
}
|
||||
a.users.Set(app.Id(), infos)
|
||||
}
|
||||
|
||||
func (a *executor) Del(appID string) {
|
||||
a.users.DelByAppID(appID)
|
||||
}
|
||||
|
||||
func (a *executor) UserCount() int {
|
||||
return a.users.Count()
|
||||
}
|
||||
71
application/auth/para-hmac/factory.go
Normal file
71
application/auth/para-hmac/factory.go
Normal file
@@ -0,0 +1,71 @@
|
||||
package para_hmac
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/eolinker/eosc/utils/schema"
|
||||
|
||||
"github.com/eolinker/apinto/application"
|
||||
"github.com/eolinker/apinto/application/auth"
|
||||
)
|
||||
|
||||
var _ auth.IAuthFactory = (*factory)(nil)
|
||||
|
||||
var driverName = "para-hmac"
|
||||
|
||||
// Register 注册auth驱动工厂
|
||||
func Register() {
|
||||
auth.FactoryRegister(driverName, NewFactory())
|
||||
}
|
||||
|
||||
type factory struct {
|
||||
configType reflect.Type
|
||||
render *schema.Schema
|
||||
userType reflect.Type
|
||||
}
|
||||
|
||||
func (f *factory) Render() interface{} {
|
||||
return f.render
|
||||
}
|
||||
|
||||
func (f *factory) ConfigType() reflect.Type {
|
||||
return f.configType
|
||||
}
|
||||
|
||||
func (f *factory) UserType() reflect.Type {
|
||||
return f.userType
|
||||
}
|
||||
|
||||
func (f *factory) Alias() []string {
|
||||
return []string{
|
||||
"para_hmac",
|
||||
"para-hmac",
|
||||
}
|
||||
}
|
||||
|
||||
func (f *factory) PreRouters() []*auth.PreRouter {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *factory) Create(tokenName string, position string, rule interface{}) (application.IAuth, error) {
|
||||
a := &executor{
|
||||
id: toId(tokenName, position),
|
||||
tokenName: tokenName,
|
||||
position: position,
|
||||
users: application.NewUserManager(),
|
||||
}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
// NewFactory 生成一个 auth_apiKey工厂
|
||||
func NewFactory() auth.IAuthFactory {
|
||||
typ := reflect.TypeOf((*Config)(nil))
|
||||
render, _ := schema.Generate(typ, nil)
|
||||
|
||||
return &factory{configType: typ, render: render, userType: reflect.TypeOf((*User)(nil))}
|
||||
}
|
||||
|
||||
func toId(tokenName, position string) string {
|
||||
return fmt.Sprintf("%s@%s@%s", tokenName, position, driverName)
|
||||
}
|
||||
35
application/auth/para-hmac/sign.go
Normal file
35
application/auth/para-hmac/sign.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package para_hmac
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var signSort = []string{
|
||||
"Body",
|
||||
"X-App-Id",
|
||||
"X-Sequence-No",
|
||||
"X-Timestamp",
|
||||
}
|
||||
|
||||
func sign(appId string, appKey string, timestamp string, sequenceNo string, body string) string {
|
||||
headerMap := make(map[string]string)
|
||||
headerMap["X-App-Id"] = appId
|
||||
headerMap["X-Sequence-No"] = sequenceNo
|
||||
headerMap["X-Timestamp"] = timestamp
|
||||
headerMap["Body"] = base64.StdEncoding.EncodeToString([]byte(body))
|
||||
builder := strings.Builder{}
|
||||
for _, key := range signSort {
|
||||
v, ok := headerMap[key]
|
||||
if !ok || v == "" {
|
||||
continue
|
||||
}
|
||||
builder.WriteString(fmt.Sprintf("%s=%s&", key, v))
|
||||
}
|
||||
builder.WriteString(appKey)
|
||||
h := sha256.New()
|
||||
h.Write([]byte(builder.String()))
|
||||
return base64.StdEncoding.EncodeToString(h.Sum(nil))
|
||||
}
|
||||
@@ -3,6 +3,8 @@ package app
|
||||
import (
|
||||
"sync"
|
||||
|
||||
para_hmac "github.com/eolinker/apinto/application/auth/para-hmac"
|
||||
|
||||
openid_connect_jwt "github.com/eolinker/apinto/application/auth/openid-connect-jwt"
|
||||
|
||||
"github.com/eolinker/apinto/application/auth"
|
||||
@@ -39,6 +41,7 @@ func NewFactory() eosc.IExtenderDriverFactory {
|
||||
jwt.Register()
|
||||
oauth2.Register()
|
||||
openid_connect_jwt.Register()
|
||||
para_hmac.Register()
|
||||
appManager = manager.NewManager(auth.Alias(), auth.Keys())
|
||||
bean.Injection(&appManager)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user