Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

clientv3: refresh authToken when permission deny #12135

Closed

Conversation

jschwinger233
Copy link

@jschwinger233 jschwinger233 commented Jul 14, 2020

clientv3: bring watch interceptor to re-fetch auth token

watch interceptor will work only when ClientStream.RecvMsg fulfill 2 requirements:

  1. last sent message was WatchCreateRequest
  2. this received message indicates permission deny

on other situations the interceptor is transparent and insignificant.

fix:
#11954
#11121
#11381

@jschwinger233
Copy link
Author

jschwinger233 commented Jul 14, 2020

CI failed, what shoud I do to get pass? I can't even pass docker run --rm --volume=pwd:/go/src/go.etcd.io/etcd gcr.io/etcd-development/etcd-test:go1.14.3 /bin/bash -c "GOARCH=amd64 CPU=1 PASSES='integration' ./test" on upstream master HEAD.

@jschwinger233 jschwinger233 force-pushed the zc/auth-reconnect branch 6 times, most recently from 341272f to e1664e1 Compare July 19, 2020 06:32
@jschwinger233 jschwinger233 changed the title credentials: refresh authToken by GetRequestMetadata clientv3: refresh authToken when permission deny Jul 20, 2020
return
}
s.client.lg.Info("refresh auth token and resend watch request")
if err = s.client.getToken(s.ctx); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

etcd supports multiple authentication methods. If users use other authentication methods, such as certificates. have you tested this scenario(cert has no permission)?
It seems that we need to distinguish token authentication. for example, in unaryClientInterceptor.

			if callOpts.retryAuth && rpctypes.Error(lastErr) == rpctypes.ErrInvalidAuthToken {
				gterr := c.getToken(ctx)
				if gterr != nil {
					logger.Warn(
						"retrying of unary invoker failed to fetch new auth token",
						zap.String("target", cc.Target()),
						zap.Error(gterr),
					)
					return gterr // lastErr must be invalid auth token
				}
				continue
			}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the case of CN based auth, users won't supply username and password, then getToken() will be nop so it will be fine. But caring about different auth mechanisms are good point.

@jschwinger23 could you add e2e test cases for making sure this refreshing mechanism works and it won't break other auth mechanisms? If you are busy adding in other PRs is fine.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that it cannot distinguish different auth mechanisms here. I agree with @xkeyideal solution in issue #12157.

@tangcong
Copy link
Contributor

/cc @mitake can you take a look. thanks.

Copy link
Contributor

@mitake mitake left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks! Defer to @gyuho @jingyih or other maintainers.

callOpts: callOpts,
ctx: ctx,
streamerCall: func(ctx context.Context) (grpc.ClientStream, error) {

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove empty line here.

@jschwinger233
Copy link
Author

fixed by #12264, close

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

4 participants