-
Notifications
You must be signed in to change notification settings - Fork 932
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #323 from CodingSinger/auth
support sign and auth for request
- Loading branch information
Showing
17 changed files
with
761 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
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,32 @@ | ||
package extension | ||
|
||
import ( | ||
"github.com/apache/dubbo-go/filter" | ||
) | ||
|
||
var ( | ||
authenticators = make(map[string]func() filter.Authenticator) | ||
accesskeyStorages = make(map[string]func() filter.AccessKeyStorage) | ||
) | ||
|
||
func SetAuthenticator(name string, fcn func() filter.Authenticator) { | ||
authenticators[name] = fcn | ||
} | ||
|
||
func GetAuthenticator(name string) filter.Authenticator { | ||
if authenticators[name] == nil { | ||
panic("authenticator for " + name + " is not existing, make sure you have import the package.") | ||
} | ||
return authenticators[name]() | ||
} | ||
|
||
func SetAccesskeyStorages(name string, fcn func() filter.AccessKeyStorage) { | ||
accesskeyStorages[name] = fcn | ||
} | ||
|
||
func GetAccesskeyStorages(name string) filter.AccessKeyStorage { | ||
if accesskeyStorages[name] == nil { | ||
panic("accesskeyStorages for " + name + " is not existing, make sure you have import the package.") | ||
} | ||
return accesskeyStorages[name]() | ||
} |
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
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
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
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 filter | ||
|
||
import ( | ||
"github.com/apache/dubbo-go/common" | ||
"github.com/apache/dubbo-go/protocol" | ||
) | ||
|
||
type AccessKeyPair struct { | ||
AccessKey string `yaml:"accessKey" json:"accessKey,omitempty" property:"accessKey"` | ||
SecretKey string `yaml:"secretKey" json:"secretKey,omitempty" property:"secretKey"` | ||
ConsumerSide string `yaml:"consumerSide" json:"ConsumerSide,consumerSide" property:"consumerSide"` | ||
ProviderSide string `yaml:"providerSide" json:"providerSide,omitempty" property:"providerSide"` | ||
Creator string `yaml:"creator" json:"creator,omitempty" property:"creator"` | ||
Options string `yaml:"options" json:"options,omitempty" property:"options"` | ||
} | ||
|
||
// AccessKeyStorage | ||
// This SPI Extension support us to store our AccessKeyPair or load AccessKeyPair from other | ||
// storage, such as filesystem. | ||
type AccessKeyStorage interface { | ||
GetAccessKeyPair(protocol.Invocation, *common.URL) *AccessKeyPair | ||
} |
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,18 @@ | ||
package filter | ||
|
||
import ( | ||
"github.com/apache/dubbo-go/common" | ||
"github.com/apache/dubbo-go/protocol" | ||
) | ||
|
||
// Authenticator | ||
type Authenticator interface { | ||
|
||
// Sign | ||
// give a sign to request | ||
Sign(protocol.Invocation, *common.URL) error | ||
|
||
// Authenticate | ||
// verify the signature of the request is valid or not | ||
Authenticate(protocol.Invocation, *common.URL) error | ||
} |
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,31 @@ | ||
package auth | ||
|
||
import ( | ||
"github.com/apache/dubbo-go/common" | ||
"github.com/apache/dubbo-go/common/constant" | ||
"github.com/apache/dubbo-go/common/extension" | ||
"github.com/apache/dubbo-go/filter" | ||
"github.com/apache/dubbo-go/protocol" | ||
) | ||
|
||
// DefaultAccesskeyStorage | ||
// The default implementation of AccesskeyStorage | ||
type DefaultAccesskeyStorage struct { | ||
} | ||
|
||
// GetAccessKeyPair | ||
// get AccessKeyPair from url by the key "accessKeyId" and "secretAccessKey" | ||
func (storage *DefaultAccesskeyStorage) GetAccessKeyPair(invocation protocol.Invocation, url *common.URL) *filter.AccessKeyPair { | ||
return &filter.AccessKeyPair{ | ||
AccessKey: url.GetParam(constant.ACCESS_KEY_ID_KEY, ""), | ||
SecretKey: url.GetParam(constant.SECRET_ACCESS_KEY_KEY, ""), | ||
} | ||
} | ||
|
||
func init() { | ||
extension.SetAccesskeyStorages(constant.DEFAULT_ACCESS_KEY_STORAGE, GetDefaultAccesskeyStorage) | ||
} | ||
|
||
func GetDefaultAccesskeyStorage() filter.AccessKeyStorage { | ||
return &DefaultAccesskeyStorage{} | ||
} |
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,28 @@ | ||
package auth | ||
|
||
import ( | ||
"net/url" | ||
"testing" | ||
) | ||
|
||
import ( | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
import ( | ||
"github.com/apache/dubbo-go/common" | ||
"github.com/apache/dubbo-go/common/constant" | ||
invocation2 "github.com/apache/dubbo-go/protocol/invocation" | ||
) | ||
|
||
func TestDefaultAccesskeyStorage_GetAccesskeyPair(t *testing.T) { | ||
url := common.NewURLWithOptions( | ||
common.WithParams(url.Values{}), | ||
common.WithParamsValue(constant.SECRET_ACCESS_KEY_KEY, "skey"), | ||
common.WithParamsValue(constant.ACCESS_KEY_ID_KEY, "akey")) | ||
invocation := &invocation2.RPCInvocation{} | ||
storage := GetDefaultAccesskeyStorage() | ||
accesskeyPair := storage.GetAccessKeyPair(invocation, url) | ||
assert.Equal(t, "skey", accesskeyPair.SecretKey) | ||
assert.Equal(t, "akey", accesskeyPair.AccessKey) | ||
} |
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,43 @@ | ||
package auth | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
) | ||
import ( | ||
"github.com/apache/dubbo-go/common/constant" | ||
"github.com/apache/dubbo-go/common/extension" | ||
"github.com/apache/dubbo-go/common/logger" | ||
"github.com/apache/dubbo-go/filter" | ||
"github.com/apache/dubbo-go/protocol" | ||
) | ||
|
||
// ConsumerSignFilter | ||
// This filter is working for signing the request on consumer side | ||
type ConsumerSignFilter struct { | ||
} | ||
|
||
func init() { | ||
extension.SetFilter(constant.CONSUMER_SIGN_FILTER, getConsumerSignFilter) | ||
} | ||
|
||
func (csf *ConsumerSignFilter) Invoke(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { | ||
logger.Infof("invoking ConsumerSign filter.") | ||
url := invoker.GetUrl() | ||
|
||
err := doAuthWork(&url, func(authenticator filter.Authenticator) error { | ||
return authenticator.Sign(invocation, &url) | ||
}) | ||
if err != nil { | ||
panic(fmt.Sprintf("Sign for invocation %s # %s failed", url.ServiceKey(), invocation.MethodName())) | ||
|
||
} | ||
return invoker.Invoke(ctx, invocation) | ||
} | ||
|
||
func (csf *ConsumerSignFilter) OnResponse(ctx context.Context, result protocol.Result, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { | ||
return result | ||
} | ||
func getConsumerSignFilter() filter.Filter { | ||
return &ConsumerSignFilter{} | ||
} |
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,37 @@ | ||
package auth | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
) | ||
|
||
import ( | ||
"github.com/golang/mock/gomock" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
import ( | ||
"github.com/apache/dubbo-go/common" | ||
"github.com/apache/dubbo-go/common/constant" | ||
"github.com/apache/dubbo-go/protocol" | ||
"github.com/apache/dubbo-go/protocol/invocation" | ||
"github.com/apache/dubbo-go/protocol/mock" | ||
) | ||
|
||
func TestConsumerSignFilter_Invoke(t *testing.T) { | ||
url, _ := common.NewURL(context.TODO(), "dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider?interface=com.ikurento.user.UserProvider&group=gg&version=2.6.0") | ||
url.SetParam(constant.SECRET_ACCESS_KEY_KEY, "sk") | ||
url.SetParam(constant.ACCESS_KEY_ID_KEY, "ak") | ||
inv := invocation.NewRPCInvocation("test", []interface{}{"OK"}, nil) | ||
filter := &ConsumerSignFilter{} | ||
ctrl := gomock.NewController(t) | ||
defer ctrl.Finish() | ||
invoker := mock.NewMockInvoker(ctrl) | ||
result := &protocol.RPCResult{} | ||
invoker.EXPECT().Invoke(inv).Return(result).Times(2) | ||
invoker.EXPECT().GetUrl().Return(url).Times(2) | ||
assert.Equal(t, result, filter.Invoke(context.Background(), invoker, inv)) | ||
|
||
url.SetParam(constant.SERVICE_AUTH_KEY, "true") | ||
assert.Equal(t, result, filter.Invoke(context.Background(), invoker, inv)) | ||
} |
Oops, something went wrong.