Disable policy check when pull without bearer token

This commit is to fix https://github.com/goharbor/harbor/issues/9780.
To align with OCI spec, when a docker pull request without bearer token in header comes in, Harbor should not intecepte it(return a 412 if check fail)
when the policy check is enabled. As the 401 is expected by the docker/caller, and then to ask token service which url is in the 401 header.

Signed-off-by: wang yan <wangyan@vmware.com>
This commit is contained in:
wang yan 2019-11-08 13:59:27 +08:00
parent a2dcdf8948
commit 415bdfa61f
4 changed files with 24 additions and 0 deletions

View File

@ -49,6 +49,10 @@ func (cth contentTrustHandler) ServeHTTP(rw http.ResponseWriter, req *http.Reque
cth.next.ServeHTTP(rw, req) cth.next.ServeHTTP(rw, req)
return return
} }
if pullWithBearer, ok := util.DockerPullAuthFromContext(req.Context()); ok && !pullWithBearer {
cth.next.ServeHTTP(rw, req)
return
}
if scannerPull, ok := util.ScannerPullFromContext(req.Context()); ok && scannerPull { if scannerPull, ok := util.ScannerPullFromContext(req.Context()); ok && scannerPull {
cth.next.ServeHTTP(rw, req) cth.next.ServeHTTP(rw, req)
return return

View File

@ -43,6 +43,8 @@ func (r *regTokenHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
r.next.ServeHTTP(rw, req) r.next.ServeHTTP(rw, req)
return return
} }
*req = *(req.WithContext(util.NewDockerPullAuthContext(req.Context(), true)))
rawToken := parts[1] rawToken := parts[1]
opt := pkg_token.DefaultTokenOptions() opt := pkg_token.DefaultTokenOptions()
regTK, err := pkg_token.Parse(opt, rawToken, &registry.Claim{}) regTK, err := pkg_token.Parse(opt, rawToken, &registry.Claim{})

View File

@ -51,6 +51,8 @@ const (
ImageInfoCtxKey = contextKey("ImageInfo") ImageInfoCtxKey = contextKey("ImageInfo")
// ScannerPullCtxKey the context key for robot account to bypass the pull policy check. // ScannerPullCtxKey the context key for robot account to bypass the pull policy check.
ScannerPullCtxKey = contextKey("ScannerPullCheck") ScannerPullCtxKey = contextKey("ScannerPullCheck")
// DockerPullAuthCtxKey the context key to index whether docker pull request with bearer token
DockerPullAuthCtxKey = contextKey("DockerPullWithBearer")
// TokenUsername ... // TokenUsername ...
// TODO: temp solution, remove after vmware/harbor#2242 is resolved. // TODO: temp solution, remove after vmware/harbor#2242 is resolved.
TokenUsername = "harbor-core" TokenUsername = "harbor-core"
@ -457,6 +459,17 @@ func ScannerPullFromContext(ctx context.Context) (bool, bool) {
return info, ok return info, ok
} }
// NewDockerPullAuthContext returns context with bearer token
func NewDockerPullAuthContext(ctx context.Context, withBearer bool) context.Context {
return context.WithValue(ctx, DockerPullAuthCtxKey, withBearer)
}
// DockerPullAuthFromContext returns whether the docker pull with bearer
func DockerPullAuthFromContext(ctx context.Context) (bool, bool) {
info, ok := ctx.Value(DockerPullAuthCtxKey).(bool)
return info, ok
}
// NewBlobInfoContext returns context with blob info // NewBlobInfoContext returns context with blob info
func NewBlobInfoContext(ctx context.Context, info *BlobInfo) context.Context { func NewBlobInfoContext(ctx context.Context, info *BlobInfo) context.Context {
return context.WithValue(ctx, blobInfoKey, info) return context.WithValue(ctx, blobInfoKey, info)

View File

@ -52,6 +52,11 @@ func (vh vulnerableHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request)
return return
} }
if pullWithBearer, ok := util.DockerPullAuthFromContext(req.Context()); ok && !pullWithBearer {
vh.next.ServeHTTP(rw, req)
return
}
if scannerPull, ok := util.ScannerPullFromContext(req.Context()); ok && scannerPull { if scannerPull, ok := util.ScannerPullFromContext(req.Context()); ok && scannerPull {
vh.next.ServeHTTP(rw, req) vh.next.ServeHTTP(rw, req)
return return