-
Notifications
You must be signed in to change notification settings - Fork 204
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
226 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters