Аутентификация службы реестра Amazon Elastic Container отличается от спецификации токена Docker

Я пытаюсь получить информацию о манифестах изображений из различных реестров изображений контейнеров. Для проверки подлинности я внедрил спецификацию токена ( https://docs.docker.com/registry/spec/auth/token/) от Docker, и, похоже, он работает с Docker Hub (общедоступными и частными хранилищами), Azure. Служба реестра контейнеров и Служба реестра контейнеров Google. Похоже, что службе реестра AWS Elastic Container требуется дополнительный вызов API GetAuthorizationToken, который возвращает имя пользователя и пароль для использования в базовой аутентификации Http. Правильно ли мое понимание того, что (согласно спецификации токена Docker) я никак не могу использовать фиксированную пару имени пользователя и пароля, а затем, используя заголовок запроса WWW-Authenticate, могу получить токен-носитель для получения токена доступа?

Задача, с которой я сейчас сталкиваюсь, заключается в том, что мне нужно выполнить особую проверку подлинности моего кода на основе того, является ли он AWS ECR по сравнению с другими службами реестра.

Мой код C# до сих пор:

class Program
{
    internal sealed class BearerToken
    {
        public string token;
        public string access_token;
        public string scope;
        public string expires_in;
        public string issued_at;
        public string refresh_token;
    }

    private static HttpClient httpClient = new HttpClient()
    {
        Timeout = TimeSpan.FromSeconds(100)
    };

    static void Main(string[] args)
    {
        string imagename = "hello-world:latest";
        Uri manifestUri = new Uri("https://619296171463.dkr.ecr.us-east-2.amazonaws.com/v2/hello-world/manifests/latest");

        // aws access key id
        //string username = "AWSACCESSKEYID";

        // aws secret access key
        //string password = "AWSSECRETACCESSKEY";

        // aws ecr get-login output
        string username = "AWS";
        string password = "24HRSLONGPASSWORDSTRING";

        HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, manifestUri);
        requestMessage.Headers.Add("Accept", "application/vnd.docker.distribution.manifest.v2+json");

        HttpResponseMessage responseMessage = httpClient.SendAsync(requestMessage, HttpCompletionOption.ResponseContentRead, CancellationToken.None).GetAwaiter().GetResult();

        if (responseMessage.StatusCode == HttpStatusCode.Unauthorized)
        {
            /*string authorizationHeaderChallenge = responseMessage.Headers.WwwAuthenticate.ToString();
            string[] challengeItems = authorizationHeaderChallenge.Split(new char[] { ' ' }, 2);
            string authScheme = challengeItems[0];
            string authParamFormat = @"(?<key>\w+)=([""'])(?<value>.*)([""'])";
            Regex authParamRegEx = new Regex(authParamFormat);
            var authParamsItems = challengeItems[1].Split(',');
            Dictionary<string, string> authParams = new Dictionary<string, string>();
            foreach (var authParam in authParamsItems)
            {
                var match = authParamRegEx.Match(authParam);
                authParams[match.Groups["key"].Value] = match.Groups["value"].Value;
            }

            UriBuilder uriBuilder = new UriBuilder($"{authParams["realm"]}");
            //string query = $"{"scope"}={"repository:containerimageinfoproject/demo-image:pull"}&{ "service"}={authParams["service"]}";
            string query = $"{"service"}={authParams["service"]}";
            uriBuilder.Query = query;

            Uri authorizationEndPoint = uriBuilder.Uri;*/

            string authenticationTokenValue = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{username}:{password}"));

            requestMessage = new HttpRequestMessage(HttpMethod.Get, manifestUri);
            requestMessage.Headers.Authorization =
                new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", authenticationTokenValue);

            responseMessage = httpClient.SendAsync(requestMessage, HttpCompletionOption.ResponseContentRead, CancellationToken.None).GetAwaiter().GetResult();

            string response = responseMessage.Content.ReadAsStringAsync().GetAwaiter().GetResult();

            /*BearerToken bearerToken = JsonConvert.DeserializeObject<BearerToken>(response);

            requestMessage = new HttpRequestMessage(HttpMethod.Get, manifestUri);
            requestMessage.Headers.Add("Accept", "application/vnd.docker.distribution.manifest.v2+json");
            requestMessage.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", bearerToken.token);

            responseMessage = httpClient.SendAsync(requestMessage, HttpCompletionOption.ResponseContentRead, CancellationToken.None).GetAwaiter().GetResult();*/
        }
    }
}

Здесь, если я использую (имя пользователя, пароль) = (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY), то я продолжаю получать:

{StatusCode: 401, ReasonPhrase: 'Unauthorized', Версия: 1.1, Содержимое: System.Net.Http.StreamContent, Заголовки: { Docker-Distribution-Api-Version: registry/2.0 Соединение: keep-alive Дата: среда, 01 августа 2018 21:40:37 GMT WWW-Authenticate: Basic realm="https://619296171463.dkr.ecr.us-east-2.amazonaws.com/",service="ecr.amazonaws.com" Длина содержимого: 15 Content-Type: текст / обычный текст; charset=utf-8 }}

Принимая во внимание, что если я использую (имя пользователя, пароль) = ("AWS", "LONGPASSWORD_GENERATED_USING_AWS_ECR_GETLOGIN"), я могу получить манифест изображения.

0 ответов

Другие вопросы по тегам