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

support identitytoken based authentication #842

Closed
wants to merge 2 commits into from

Conversation

lbruun
Copy link

@lbruun lbruun commented Mar 19, 2023

This form of authentication is typically used by private registries which use OAuth2 authentication, for example Azure Container Registry (ACR). Specifically this PR fixes the situation where the identity token is given directly in the Docker config.json file.

What does this PR do?

Proposes a fix for issue 841

Note: It is outside the scope of testcontainers library to obtain the token.

Ref : Docker's documentation

Why is it important?

Support for Azure Container Registry from CI pipeline.

Related issues

Relates #841

How to test this PR

  1. Have the Azure CLI installed.
  2. Use a private Azure Container Registry. By private is meant one that doesn't allow un-authenticated pulls.
  3. Login to Azure with an identity which is allowed to pull from that registry: az login
  4. Perform implicit docker login: az acr login -name myprivateregistry. This obtains a 3 hour token and uses the docker CLI to write the identitytoken into your local Docker config file. If you are doing this on a host which has a credstore available then "unfortunately" the Docker CLI is clever enough to use that. This is not good, as then you'll be testing something which testcontainers-dotnet already knows how to handle. The workaround for that is to do as follows:
TOKEN=$(az acr login --name myprivateregistry --expose-token --output tsv --query accessToken)
docker login myprivateregistry.azurecr.io --username 00000000-0000-0000-0000-000000000000 --password $TOKEN
  1. Look in your ~/.docker/config.json and verify that is has an explicit identitytoken.
  2. Do the test.

Implementation notes

This PR simply enhances on the Base64Provider class. This is a little bit quick-and-dirty as technically identitytoken-based authentication has nothing to do with base64, so the name is slightly misleading for the identitytoken use-case. It may be "cleaner" to create a new provider class, e.g. IdentityTokenProvider.cs, although it would share 90% of its code with the existing Base64Provider.

This form of authentication is typically used by private registries
which use OAuth2 authentication, for example Azure Container Registry (ACR).

Note: It is outside the scope of testcontainers to _obtain_ the token.
@netlify
Copy link

netlify bot commented Mar 19, 2023

Deploy Preview for testcontainers-dotnet ready!

Name Link
🔨 Latest commit 7802081
🔍 Latest deploy log https://app.netlify.com/sites/testcontainers-dotnet/deploys/64212fd8012ac000084c9ebc
😎 Deploy Preview https://deploy-preview-842--testcontainers-dotnet.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site settings.

@lbruun lbruun changed the title fix: support identitytoken based authentication support identitytoken based authentication Mar 20, 2023
Comment on lines +65 to +83
if (!JsonValueKind.Object.Equals(authProperty.Value.ValueKind))
{
return null;
}

// if the json object has a property named 'identitytoken' then that value is all we need
// to authenticate. (no need for username or password as it is implied by the token)

if (authProperty.Value.TryGetProperty("identitytoken", out var identitytoken))
{
if (JsonValueKind.String.Equals(identitytoken.ValueKind))
{
this.logger.DockerRegistryCredentialFound(hostname);
return new DockerRegistryAuthenticationConfiguration(authProperty.Name, null, null, identitytoken.GetString());
}
}

// ... otherwise we expect the 'auth' property to contain the username and password
// in base64 encoded form and separated by a colon char.
Copy link
Collaborator

@HofmeisterAn HofmeisterAn Mar 23, 2023

Choose a reason for hiding this comment

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

Suggested change
if (!JsonValueKind.Object.Equals(authProperty.Value.ValueKind))
{
return null;
}
// if the json object has a property named 'identitytoken' then that value is all we need
// to authenticate. (no need for username or password as it is implied by the token)
if (authProperty.Value.TryGetProperty("identitytoken", out var identitytoken))
{
if (JsonValueKind.String.Equals(identitytoken.ValueKind))
{
this.logger.DockerRegistryCredentialFound(hostname);
return new DockerRegistryAuthenticationConfiguration(authProperty.Name, null, null, identitytoken.GetString());
}
}
// ... otherwise we expect the 'auth' property to contain the username and password
// in base64 encoded form and separated by a colon char.
if (JsonValueKind.Undefined.Equals(authProperty.Value.ValueKind))
{
return null;
}
if (authProperty.Value.TryGetProperty("identityToken", out var identityToken) && !string.IsNullOrEmpty(identityToken.GetString()))
{
_logger.DockerRegistryCredentialFound(hostname);
return new DockerRegistryAuthenticationConfiguration(authProperty.Name, null, null, identityToken.GetString());
}

Can you please cover the changes with tests.

@HofmeisterAn
Copy link
Collaborator

Due to inactivity, I will be closing this pull request. However, please do not hesitate to reopen it again if you decide to resume working on it.

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

Successfully merging this pull request may close these issues.

2 participants