-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Handle "<token>" as Username from credential helpers. #1490
Comments
I on working on a PR regarding the logic of https://github.com/containerd/containerd/blob/master/remotes/docker/authorizer.go#L189 and https://github.com/docker/distribution/blob/master/registry/client/auth/session.go#L335 |
@andxu thanks! It might be a bit involved and I would recommend outlining your approach here first and splitting the work into multiple subtasks. Let us know if you have any questions! |
@coollog Thanks for the advice. I will post it here later today. |
First, let's take a look how docker gets the credentials from docker-credential-helper(see inline comments added). // https://github.com/docker/cli/blob/master/cli/config/credentials/native_store.go#L115
// andy: get crendentials from executing echo "$serverAddress"|docker-credential-helper get
creds, err := client.Get(c.programFunc, serverAddress)
if err != nil {
...
}
// andy: here tokenUsername = "<token>"
if creds.Username == tokenUsername {
// andy: token auth
ret.IdentityToken = creds.Secret
} else {
// andy: basic auth
ret.Password = creds.Secret
ret.Username = creds.Username
}
ret.ServerAddress = serverAddress // https://github.com/docker/distribution/blob/master/registry/client/auth/session.go#L478
func (th *tokenHandler) fetchToken(params map[string]string, scopes []string) (token string, expiration time.Time, err error) {
...
var refreshToken string
if th.creds != nil {
refreshToken = th.creds.RefreshToken(realmURL, service)
}
if refreshToken != "" || th.forceOAuth {
// andy: token auth
return th.fetchTokenWithOAuth(realmURL, refreshToken, service, scopes)
}
// andy: basic auth
return th.fetchTokenWithBasicAuth(realmURL, service, scopes)
}
// https://github.com/docker/cli/blob/ae1618713f83e7da07317d579d0675f578de22fa/cli/trust/trust.go#L89
func (scs simpleCredentialStore) RefreshToken(u *url.URL, service string) string {
return scs.auth.IdentityToken
} Through above code, in jib, I suggest to change(here takes pull image for example, push is similar):
// pseudocode for BaseImageWithAuthorization call()
Credential Credential registryCredential = NonBlockingSteps.get(retrieveBaseRegistryCredentialsStep); = NonBlockingSteps.get(retrieveBaseRegistryCredentialsStep);
registryAuthenticator.setCredential(registryCredential).authenticatePull();
// https://github.com/GoogleContainerTools/jib/blob/master/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryAuthenticator.java#L264
// pseudocode
private Authorization authenticate(String scope) throws RegistryAuthenticationFailedException {
...
AuthenticationResponseTemplate responseJson = null;
if (credential != null) {
if (StringUtils.isNotBlank(credential.getRefreshToken())) {
// example:
// POST: https://andyreg.azurecr.io/oauth2/token
// Body: grant_type=refresh_token&service=andyreg.azurecr.io&scope=repository:ubuntu:pull&refresh_token=<eyJhbGciOi...88Q>
responseJson = fetchTokenWithOAuth(credential, realm, service, scope);
} else {
// example:
// GET: https://auth.docker.io/token?service=registry.docker.io&scope=repository:ubuntu:pull
responseJson = fetchTokenWithBasicAuth(credential, realm, service, scope);
}
}
if (responseJson.getToken() == null) {
throw new RegistryAuthenticationFailedException(
registryEndpointRequestProperties.getServerUrl(),
registryEndpointRequestProperties.getImageName(),
"Did not get token in authentication response from " + authenticationUrl);
}
return Authorizations.withBearerToken(responseJson.getToken());
} |
@andxu Thanks for the writeup!
|
I am adding test cases, please take a review of my implementation, thanks |
Fixed by #1511. Jib will be able to use ACR through an OAuth2 token retrieved from ACR credential helpers. |
@coollog @chanseokoh Thank you all for your works to make acr supported. |
The Docker Credential helper protocol specifies:
Jib should consider the case where the username received from a credential helper is
<token>
and authenticate by using theSecret
as an identity token. See Azure/acr-docker-credential-helper#31 (comment) for an example.Originates from Azure/acr-docker-credential-helper#31 (comment)
The text was updated successfully, but these errors were encountered: