访问控制支持基本认证和子请求认证

This commit is contained in:
刘祥超
2021-06-19 21:36:13 +08:00
parent dcdb6a923a
commit ddacb945e1
5 changed files with 53 additions and 46 deletions

View File

@@ -3,9 +3,7 @@
package serverconfigs
import (
"encoding/base64"
"encoding/json"
stringutil "github.com/iwind/TeaGo/utils/string"
"net/http"
)
@@ -13,23 +11,17 @@ import (
type HTTPAuthBasicMethodUser struct {
Username string `json:"username"`
Password string `json:"password"`
Encoder string `json:"encoding"`
}
func (this *HTTPAuthBasicMethodUser) Validate(password string) (bool, error) {
switch this.Encoder {
case "md5":
return this.Password == stringutil.Md5(password), nil
case "base64":
return this.Password == base64.StdEncoding.EncodeToString([]byte(password)), nil
default:
return this.Password == password, nil
}
}
// HTTPAuthBasicMethod BasicAuth方法定义
type HTTPAuthBasicMethod struct {
Users []*HTTPAuthBasicMethodUser `json:"users"`
Realm string `json:"realm"`
Charset string `json:"charset"`
userMap map[string]*HTTPAuthBasicMethodUser // username => *User
}

View File

@@ -6,7 +6,6 @@ import (
"encoding/base64"
"github.com/iwind/TeaGo/assert"
"github.com/iwind/TeaGo/maps"
stringutil "github.com/iwind/TeaGo/utils/string"
"net/http"
"testing"
)
@@ -35,30 +34,6 @@ func TestHTTPAuthBasicMethodUser_Validate(t *testing.T) {
}
a.IsFalse(b)
}
{
user := &HTTPAuthBasicMethodUser{
Password: stringutil.Md5("123456"),
Encoder: "md5",
}
b, err := user.Validate("123456")
if err != nil {
t.Fatal(err)
}
a.IsTrue(b)
}
{
user := &HTTPAuthBasicMethodUser{
Password: base64.StdEncoding.EncodeToString([]byte("123456")),
Encoder: "base64",
}
b, err := user.Validate("123456")
if err != nil {
t.Fatal(err)
}
a.IsTrue(b)
}
}
func TestHTTPAuthBasicMethod_Filter(t *testing.T) {

View File

@@ -0,0 +1,31 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
package serverconfigs
type HTTPAuthType = string
const (
HTTPAuthTypeBasicAuth HTTPAuthType = "basicAuth" // BasicAuth
HTTPAuthTypeSubRequest HTTPAuthType = "subRequest" // 子请求
)
type HTTPAuthTypeDefinition struct {
Name string `json:"name"`
Code string `json:"code"`
Description string `json:"description"`
}
func FindAllHTTPAuthTypes() []*HTTPAuthTypeDefinition {
return []*HTTPAuthTypeDefinition{
{
Name: "基本认证",
Code: HTTPAuthTypeBasicAuth,
Description: "BasicAuth最简单的HTTP请求认证方式通过传递<span class=\"ui label tiny basic text\">Authorization: Basic xxx</span> Header认证。",
},
{
Name: "子请求",
Code: HTTPAuthTypeSubRequest,
Description: "通过自定义的URL子请求来认证请求。",
},
}
}

View File

@@ -7,13 +7,6 @@ import (
"net/http"
)
type HTTPAuthType = string
const (
HTTPAuthTypeBasicAuth HTTPAuthType = "basicAuth" // BasicAuth
HTTPAuthTypeSubRequest HTTPAuthType = "subRequest" // 子请求
)
// HTTPAuthPolicy HTTP认证策略
type HTTPAuthPolicy struct {
Id int64 `json:"id"`
@@ -53,3 +46,8 @@ func (this *HTTPAuthPolicy) Filter(req *http.Request, subReqFunc func(subReq *ht
}
return this.method.Filter(req, subReqFunc, formatter)
}
// Method 获取认证实例
func (this *HTTPAuthPolicy) Method() HTTPAuthMethodInterface {
return this.method
}

View File

@@ -65,16 +65,26 @@ func (this *HTTPAuthSubRequestMethod) Filter(req *http.Request, doSubReq func(su
}
var url = formatter(this.URL)
var scheme = "http"
if req.TLS != nil {
scheme = "https"
}
var host = req.URL.Host
if len(host) > 0 {
host = req.Host
}
if !this.isFullURL {
url = req.URL.Scheme + "://" + req.URL.Host + url
url = scheme + "://" + host + url
}
newReq, err := http.NewRequest(method, url, nil)
if err != nil {
return false, err
}
for k, v := range req.Header {
if k != "Connection" {
newReq.Header[k] = v
}
}
if !this.isFullURL {
status, err := doSubReq(newReq)
@@ -84,6 +94,7 @@ func (this *HTTPAuthSubRequestMethod) Filter(req *http.Request, doSubReq func(su
return status >= 200 && status < 300, nil
}
newReq.Header.Set("Referer", req.URL.String())
resp, err := httpAuthSubRequestHTTPClient.Do(newReq)
if err != nil {
return false, err