Skip to content

401 Unauthorized on some API endpoints when using OIDC #16647

Description

@SimonAlling

Expected behavior and actual behavior

I expect to be able to access all API endpoints that my user has access to via e.g. curl, using my CLI secret for authentication.

However, when using an OIDC user account, I cannot access some endpoints:

  • I can GET the list of projects, but I cannot GET a specific project.
  • I can GET the list of repositories in a project, but I cannot GET a specific repository.
  • I can GET the list of artifacts in a repository, but I cannot GET a specific artifact (or e.g. its vulnerabilities).

Specifically, when using curl, I get a 401 response with this body:

{"errors":[{"code":"UNAUTHORIZED","message":"unauthorized"}]}

I can access all endpoints with curl using a robot account or the admin account (which do not use OIDC).

I can also access all endpoints in the web GUI and the API Explorer (/devcenter-api-2.0) using my OIDC account.

Steps to reproduce the problem

HARBOR_USERNAME="bob"
 HARBOR_PASSWORD=""
HARBOR_URL="https://example.com"
HARBOR_PROJECT="foo"
HARBOR_REPO="bar"
HARBOR_TAG="baz"
API_PATHS=(
    "/projects"
    "/projects/${HARBOR_PROJECT:?}"
    "/projects/${HARBOR_PROJECT:?}/repositories"
    "/projects/${HARBOR_PROJECT:?}/repositories/${HARBOR_REPO:?}"
    "/projects/${HARBOR_PROJECT:?}/repositories/${HARBOR_REPO:?}/artifacts"
    "/projects/${HARBOR_PROJECT:?}/repositories/${HARBOR_REPO:?}/artifacts/${HARBOR_TAG:?}"
    "/projects/${HARBOR_PROJECT:?}/repositories/${HARBOR_REPO:?}/artifacts/${HARBOR_TAG:?}/additions/vulnerabilities"
)

for apiPath in "${API_PATHS[@]}"; do
    curl --silent --output /dev/null --write-out "%{http_code} %{url_effective}\n" -u ${HARBOR_USERNAME:?}:${HARBOR_PASSWORD:?} "${HARBOR_URL:?}/api/v2.0${apiPath}"
done

Output:

200 https://example.com/api/v2.0/projects
401 https://example.com/api/v2.0/projects/foo
200 https://example.com/api/v2.0/projects/foo/repositories
401 https://example.com/api/v2.0/projects/foo/repositories/bar
200 https://example.com/api/v2.0/projects/foo/repositories/bar/artifacts
401 https://example.com/api/v2.0/projects/foo/repositories/bar/artifacts/baz
401 https://example.com/api/v2.0/projects/foo/repositories/bar/artifacts/baz/additions/vulnerabilities

Lines like this one show up in the log:

2022-04-04T14:00:00Z [ERROR] [/server/middleware/security/basic_auth.go:40][requestID="…"]: failed to authenticate bob: not supported

The error is thrown here.

Additional information

Notably, it turns out that in the web GUI and the API Explorer, a cookie named sid is included in each request. That cookie alone turns out to be enough for authentication and authorization – the Authorization header (i.e. curl's -u flag) is not even needed:

 HARBOR_SID="deadbeefdeadbeefdeadbeefdeadbeef"
curl --silent --output /dev/null --write-out "%{http_code} %{url_effective}\n" --cookie "sid=${HARBOR_SID:?}" "${HARBOR_URL:?}/api/v2.0/projects/${HARBOR_PROJECT:?}"

As previously stated, the cookie is necessary for some endpoints (when accessed by an OIDC user). However, the API Explorer generates commands like this one, without any cookie:

curl -X 'GET' \
  'https://example.com/api/v2.0/projects/foo' \
  -H 'accept: application/json' \
  -H 'X-Is-Resource-Name: false' \
  -H 'authorization: Basic Ym9iOm15IENMSSBzZWNyZXQK'

All in all, there seems to be some inconsistency regarding OIDC authentication:

  • When the API is accessed by an OIDC user, some endpoints (e.g. /projects/foo) require an OIDC cookie, while others (e.g. /projects) do not.
  • In the API Explorer, commands without necessary authentication information are displayed.

Versions

  • Harbor version: 2.4.1
  • docker engine version: N/A
  • docker-compose version: N/A

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions