mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-18 14:47:38 +01:00
v2 auth middleware handles the ping request from internal
When scanner like trivy handles the auth flow to pull image, it pings the /v2 and access the token service url in response body, by default it will be external endpoint of Harbor. There will be problem when Harbor is deployed on a single node with hairpinning not supported. This commit makes sure the address of token service in the challenge is internal url of core component when the request is from internal. Signed-off-by: Daniel Jiang <jiangd@vmware.com>
This commit is contained in:
parent
97a7a6dc35
commit
fe587d0cc8
@ -17,6 +17,7 @@ package v2auth
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
@ -30,7 +31,9 @@ import (
|
||||
serror "github.com/goharbor/harbor/src/server/error"
|
||||
)
|
||||
|
||||
const authHeader = "Authorization"
|
||||
const (
|
||||
authHeader = "Authorization"
|
||||
)
|
||||
|
||||
type reqChecker struct {
|
||||
pm promgr.ProjectManager
|
||||
@ -86,9 +89,9 @@ func getChallenge(req *http.Request, accessList []access) string {
|
||||
return `Basic realm="harbor"`
|
||||
}
|
||||
// No auth header, treat it as CLI and redirect to token service
|
||||
ep, err := config.ExtEndpoint()
|
||||
ep, err := tokenSvcEndpoint(req)
|
||||
if err != nil {
|
||||
logger.Errorf("failed to get the external endpoint, error: %v", err)
|
||||
logger.Errorf("failed to get the endpoint for token service, error: %v", err)
|
||||
}
|
||||
tokenSvc := fmt.Sprintf("%s/service/token", strings.TrimSuffix(ep, "/"))
|
||||
scope := ""
|
||||
@ -105,6 +108,19 @@ func getChallenge(req *http.Request, accessList []access) string {
|
||||
return challenge
|
||||
}
|
||||
|
||||
func tokenSvcEndpoint(req *http.Request) (string, error) {
|
||||
logger := log.G(req.Context())
|
||||
rawCoreURL := config.InternalCoreURL()
|
||||
if coreURL, err := url.Parse(rawCoreURL); err == nil {
|
||||
if req.Host == coreURL.Host {
|
||||
return rawCoreURL, nil
|
||||
}
|
||||
} else {
|
||||
logger.Errorf("Failed to parse core url, error: %v, fallback to external endpoint", err)
|
||||
}
|
||||
return config.ExtEndpoint()
|
||||
}
|
||||
|
||||
var (
|
||||
once sync.Once
|
||||
checker reqChecker
|
||||
|
@ -92,6 +92,7 @@ func TestMain(m *testing.M) {
|
||||
}
|
||||
conf := map[string]interface{}{
|
||||
common.ExtEndpoint: "https://harbor.test",
|
||||
common.CoreURL: "https://harbor.core:8443",
|
||||
}
|
||||
config.InitWithSettings(conf)
|
||||
if rc := m.Run(); rc != 0 {
|
||||
@ -238,12 +239,14 @@ func TestGetChallenge(t *testing.T) {
|
||||
}))
|
||||
req3x := req3.Clone(req3.Context())
|
||||
req3x.SetBasicAuth("", "")
|
||||
req3x.Host = "harbor.test"
|
||||
req4, _ := http.NewRequest(http.MethodGet, "https://registry.test/v2/project_1/hello-world/manifests/v1", nil)
|
||||
req4 = req4.WithContext(lib.WithArtifactInfo(context.Background(), lib.ArtifactInfo{
|
||||
Repository: "project_1/hello-world",
|
||||
Reference: "v1",
|
||||
ProjectName: "project_1",
|
||||
}))
|
||||
req4.Host = "harbor.core:8443"
|
||||
|
||||
cases := []struct {
|
||||
request *http.Request
|
||||
@ -275,7 +278,7 @@ func TestGetChallenge(t *testing.T) {
|
||||
},
|
||||
{
|
||||
request: req4,
|
||||
challenge: `Bearer realm="https://harbor.test/service/token",service="harbor-registry",scope="repository:project_1/hello-world:pull"`,
|
||||
challenge: `Bearer realm="https://harbor.core:8443/service/token",service="harbor-registry",scope="repository:project_1/hello-world:pull"`,
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
|
Loading…
Reference in New Issue
Block a user