yarpc / yarpc-go

A message passing platform for Go
MIT License
412 stars 103 forks source link

Authentication middleware for yarpc clients #698

Closed anuptalwalkar closed 7 years ago

anuptalwalkar commented 7 years ago

Fx needs to integrate authentication on the client side for transport modules. Currently for uhttp module, we hand out client.New with authentication filter enabled and allow clients to be authenticated for making requests (https://github.com/uber-go/fx/blob/master/modules/uhttp/client/client_filters.go).

We will need similar behavior for YARPC request authentication. Is implementing and integrating OutboundMiddleware on YARPC clients the right way to approach this? I am wondering if making configurable clients should be located with YARPC and allow some way to inject client filters or as a client wrapper in Fx. Thoughts?

HelloGrayson commented 7 years ago

re:auth in middleware - that is how we've been envisioning authn/z features being implemented.

For client-side only auth, it could be that OutboundMiddleware is enough.

For auth that requires some server/client cooperation, #653 would likely be needed.

anuptalwalkar commented 7 years ago

Yes filter in uhttp is same as outbound middleware for RPC.

Do you have any examples on how OutboundMiddleware is integrated with the client? I am a bit confused on how to make it available with UberFx on start since currently thriftrw generates the clients and wrappers.

HelloGrayson commented 7 years ago

Outbound middleware is configured when the Dispatcher is instantiated, not on the client.

Here is an example.

Searching "outboundmiddleware" will surface other places this is referenced:

go.uber.org/yarpc - [dev] » ag outboundmiddleware
api/middleware/outbound_test.go
39:func TestUnaryNopOutboundMiddleware(t *testing.T) {
65:func TestOnewayNopOutboundMiddleware(t *testing.T) {

dispatcher.go
62: OutboundMiddleware OutboundMiddleware
76:// OutboundMiddleware contains the different types of outbound middlewares.
77:type OutboundMiddleware struct {
105:        outbounds:         convertOutbounds(cfg.Outbounds, cfg.OutboundMiddleware),
112:func convertOutbounds(outbounds Outbounds, mw OutboundMiddleware) Outbounds {

CHANGELOG.md
341:    `UnaryInboundMiddleware` and `UnaryOutboundMiddleware` respectively.
343:    `InboundMiddleware` and `OutboundMiddleware` fields.
353:            OutboundMiddleware: yarpc.OutboundMiddleware{Unary: myFilter},
357:    `OnewayOutboundMiddleware` interfaces.

internal/examples/json-keyvalue/client/main.go
103:        OutboundMiddleware: yarpc.OutboundMiddleware{
104:            Unary: yarpc.UnaryOutboundMiddleware(requestLogOutboundMiddleware{}),

internal/examples/json-keyvalue/client/logger.go
30:type requestLogOutboundMiddleware struct{}
32:func (requestLogOutboundMiddleware) Call(

internal/examples/thrift-keyvalue/keyvalue/client/cache.go
33:// CacheOutboundMiddleware is a OutboundMiddleware
34:type CacheOutboundMiddleware interface {
45:type cacheOutboundMiddleware map[string]entry
47:// NewCacheOutboundMiddleware builds a new CacheOutboundMiddleware.
48:func NewCacheOutboundMiddleware() CacheOutboundMiddleware {
49: cache := make(cacheOutboundMiddleware)
53:func (c *cacheOutboundMiddleware) Invalidate() {
55: *c = make(cacheOutboundMiddleware)
58:func (c *cacheOutboundMiddleware) Call(ctx context.Context, request *transport.Request, out transport.UnaryOutbound) (*transport.Response, error) {

internal/examples/thrift-keyvalue/keyvalue/client/main.go
66: cache := NewCacheOutboundMiddleware()
74:     OutboundMiddleware: yarpc.OutboundMiddleware{

internal/outboundmiddleware/chain_test.go
21:package outboundmiddleware
39:type countOutboundMiddleware struct{ Count int }
41:func (c *countOutboundMiddleware) Call(
47:func (c *countOutboundMiddleware) CallOneway(ctx context.Context, req *transport.Request, o transport.OnewayOutbound) (transport.Ack, error) {
83: before := &countOutboundMiddleware{}
84: after := &countOutboundMiddleware{}
123:    before := &countOutboundMiddleware{}
124:    after := &countOutboundMiddleware{}

internal/outboundmiddleware/chain.go
21:package outboundmiddleware

middleware.go
26: "go.uber.org/yarpc/internal/outboundmiddleware"
29:// UnaryOutboundMiddleware combines the given collection of unary outbound
31:func UnaryOutboundMiddleware(mw ...middleware.UnaryOutbound) middleware.UnaryOutbound {
32: return outboundmiddleware.UnaryChain(mw...)
41:// OnewayOutboundMiddleware combines the given collection of unary outbound
43:func OnewayOutboundMiddleware(mw ...middleware.OnewayOutbound) middleware.OnewayOutbound {
44: return outboundmiddleware.OnewayChain(mw...)

yarpctest/recorder/recorder_test.go
172:        OutboundMiddleware: yarpc.OutboundMiddleware{
206:        OutboundMiddleware: yarpc.OutboundMiddleware{

yarpctest/recorder/recorder.go
44://      OutboundMiddleware: yarpc.OutboundMiddleware {
kriskowal commented 7 years ago

@anuptalwalkar has this thread concluded? Are you satisfied with our feedback?