예제 #1
0
        /// <summary>
        /// Verifies the request against a credential store.
        /// </summary>
        /// <param name="request">
        /// The request to verify.
        /// </param>
        /// <param name="credentialStore">
        /// The credential store used to verify the request.
        /// </param>
        /// <returns>
        /// true if the request validates. false for any other reason except a SigningException.
        /// </returns>
        public bool Verify(IDTARequest request, CredentialStore credentialStore)
        {
            if (!TryGetRequestDate(request.Headers,
                                   out DateTime amznAuthDateTime))
            {
                return(false);
            }

            if (!request.Headers.TryGetValue(AuthorizationHeader,
                                             out var requestAuthorization))
            {
                return(false);
            }

            if (!authenticationHeaderParser.TryParse(requestAuthorization,
                                                     out var authenticationHeader))
            {
                return(false);
            }

            // The credential info should follow this pattern: KEYID/DATE
            string[] credentialInfo = authenticationHeader.Credential.Split('/');
            if (credentialInfo.Length < 2)
            {
                return(false);
            }

            if (!credentialStore.TryGetValue(credentialInfo[0], out var credential))
            {
                return(false);
            }

            string signedHeaders = authenticationHeader.SignedHeaders;

            string[] signedHeadersList = signedHeaders.Split(';');

            if (!TryGetHeadersToSign(signedHeadersList, request.Headers, out var headersToSign))
            {
                return(false);
            }

            string date     = amznAuthDateTime.ToString(ISO8601Date);
            string dateTime = amznAuthDateTime.ToString(ISO8601DateTime);

            string canonicalHeaders = GetCanonicalHeaders(headersToSign);
            string canonicalRequest = GetCanonicalRequest(
                request.HttpMethod.ToUpperInvariant(),
                request.Uri.AbsolutePath,
                string.Empty,
                canonicalHeaders,
                signedHeaders,
                HexEncodedHash(request.Body ?? ""));

            string stringToSign = GetStringToSign(
                AlgorithmHeader,
                dateTime,
                string.Empty,
                HexEncodedHash(canonicalRequest));

            byte[] timedKey  = Sign(date, credential.SecretKey);
            string signature = Sign(stringToSign, timedKey).HexEncode();

            string computedAuthorization = GetAuthorizationHeader(signedHeaders, credential, date, signature);

            return(computedAuthorization.Equals(requestAuthorization));
        }
        /// <summary>
        /// Verifies the request against a credential store.
        /// </summary>
        /// <param name="request">
        /// the request to verify.
        /// </param>
        /// <param name="credentialStore">
        /// the credential store used to verify the request.
        /// </param>
        /// <returns>
        /// true if the request validates. false for any other reason except a SigningException.
        /// </returns>
        public bool Verify(Request request, CredentialStore credentialStore)
        {
            DateTime now      = Clock.Now();
            string   strDate  = now.ToString(DateStampFormat);
            string   dateTime = request.GetHeader(XAmzDateHeader);

            if (dateTime == null)
            {
                return(false);
            }

            // Fail if the Authentication header is not found
            string actualAuthorization = request.GetHeader(AuthorizationHeader);

            if (string.IsNullOrEmpty(actualAuthorization))
            {
                return(false);
            }

            request.RemoveHeader(AuthorizationHeader);

            // Clear any header that isn't in the list of signed signedHeaders
            AuthenticationHeader authenticationHeader = AuthenticationHeaderParser.Parse(actualAuthorization);

            if (authenticationHeader == null)
            {
                return(false);
            }

            string[] signedHeaders = authenticationHeader.SignedHeaders.Split(';');

            RemoveUnsignedHeaders(request, signedHeaders);

            DateTime dateOfRequest;

            if (!DateTime.TryParseExact(dateTime, DateTimeFormat, null, DateTimeStyles.None, out dateOfRequest))
            {
                return(false);
            }

            TimeSpan timeSpan = now - dateOfRequest;

            if (Math.Abs(timeSpan.TotalMilliseconds) > TimeToleranceInMilliseconds)
            {
                return(false);
            }

            // The credential info should follow this pattern: KEYID/DATE
            string[] credentialInfo = authenticationHeader.Credential.Split('/');

            if (credentialInfo.GetLength(0) < 2)
            {
                return(false);
            }

            Credential credential;

            try
            {
                credential = credentialStore.Get(credentialInfo[0]);
            }
            catch (CredentialNotFoundException)
            {
                return(false);
            }

            byte[] timedKey         = Sign(strDate, credential.SecretKey);
            string canonicalRequest = GetCanonicalRequest(request);
            string stringToSign     = GetStringToSign(AlgorithmHeader, dateTime, EmptyScope, canonicalRequest);
            string signature        = BitConverter.ToString(Sign(stringToSign, timedKey)).Replace("-", "").ToLower();

            string computedAuthorization = GetAuthorizatioinHeader(request, credential, strDate, signature);

            return(computedAuthorization.Equals(actualAuthorization));
        }