Amazon Elastic Container Registry Service身份验证似乎与Docker令牌规范不同

时间:2018-08-01 19:31:14

标签: amazon-web-services docker-registry aws-ecr

我正在尝试从各种容器图像注册表中获取图像清单信息。为了进行身份验证,我已经由Docker实现了令牌规范(https://docs.docker.com/registry/spec/auth/token/),它似乎可以与Docker Hub(公共和私有存储库),Azure Container Registry Service和Google Container Registry Service一起使用。看来,AWS Elastic Container Registry服务需要对GetAuthorizationToken API的额外调用,该调用返回要在基本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:“未经授权”,版本:1.1,内容:System.Net.Http.StreamContent,标头: {   Docker-Distribution-Api-Version:注册表/2.0   连接:保持活动状态   日期:2018年8月1日星期三21:40:37 GMT   WWW-Authenticate:基本领域=“ https://619296171463.dkr.ecr.us-east-2.amazonaws.com/”,service =“ ecr.amazonaws.com”   内容长度:15   内容类型:文本/纯文本;字符集= utf-8 }}

如果我使用(用户名,密码)=(“ AWS”,“ LONGPASSWORD_GENERATED_USING_AWS_ECR_GETLOGIN”),则可以获取图像清单。

0 个答案:

没有答案