Аутентификация службы реестра 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"), я могу получить манифест изображения.