public Verify()
 {
     _signature     = (Signature)TestModels.Signature.Clone();
     _signedRequest = (HttpRequestForSigning)TestModels.Request.Clone();
     _client        = new Client(TestModels.Client.Id, TestModels.Client.Name, new HMACSignatureAlgorithm("s3cr3t", HashAlgorithmName.MD5), TestModels.Client.NonceLifetime, TestModels.Client.ClockSkew, TestModels.Client.Claims);
     _method        = (request, signature, client) => _sut.Verify(request, signature, client);
 }
        public override SignatureVerificationFailure VerifySync(HttpRequestForSigning signedRequest, Signature signature, Client client)
        {
            if (
                signature.Headers.Contains(HeaderName.PredefinedHeaderNames.Created) &&
                AlgorithmNamesThatDoNotAllowCreatedHeader.Contains(client.SignatureAlgorithm.Name, StringComparer.OrdinalIgnoreCase))
            {
                return(SignatureVerificationFailure.InvalidCreatedHeader(
                           $"It is not allowed to take the {HeaderName.PredefinedHeaderNames.Created} into account, when the signature algorithm is {client.SignatureAlgorithm.Name}."));
            }

            if (!signature.Created.HasValue)
            {
                return(SignatureVerificationFailure.InvalidCreatedHeader($"The signature does not contain a value for the {nameof(signature.Created)} property, but it is required."));
            }

            var createdHeaderValues = signedRequest.Headers.GetValues(HeaderName.PredefinedHeaderNames.Created);

            if (createdHeaderValues != StringValues.Empty && signature.Headers.Contains(HeaderName.PredefinedHeaderNames.Created))
            {
                if (!long.TryParse(createdHeaderValues.First(), out var parsedCreatedValue))
                {
                    return(SignatureVerificationFailure.InvalidCreatedHeader(
                               $"The request does not contain a valid value for the {HeaderName.PredefinedHeaderNames.Created} header."));
                }

                var createdHeaderValue = DateTimeOffset.FromUnixTimeSeconds(parsedCreatedValue);
                if (createdHeaderValue != signature.Created.Value)
                {
                    return(SignatureVerificationFailure.InvalidCreatedHeader(
                               $"The signature creation time does not match the value of the {HeaderName.PredefinedHeaderNames.Created} request header."));
                }
            }

            return(null);
        }
            public VerifySignature()
            {
                _signature = new Signature {
                    KeyId = "client1"
                };

                _signedRequest = new HttpRequestForSigning {
                    Method     = HttpMethod.Post,
                    RequestUri = "https://unittest.com:9001"
                };

                _client = new Client("client1", "Unit test app", new HMACSignatureAlgorithm("s3cr3t", HashAlgorithmName.SHA256), TimeSpan.FromMinutes(1));

                A.CallTo(() => _knownAlgorithmVerificationTask.Verify(A <HttpRequestForSigning> ._, A <Signature> ._, A <Client> ._)).Returns((SignatureVerificationFailure)null);
                A.CallTo(() => _matchingAlgorithmVerificationTask.Verify(A <HttpRequestForSigning> ._, A <Signature> ._, A <Client> ._)).Returns((SignatureVerificationFailure)null);
                A.CallTo(() => _createdHeaderGuardVerificationTask.Verify(A <HttpRequestForSigning> ._, A <Signature> ._, A <Client> ._)).Returns((SignatureVerificationFailure)null);
                A.CallTo(() => _expiresHeaderGuardVerificationTask.Verify(A <HttpRequestForSigning> ._, A <Signature> ._, A <Client> ._)).Returns((SignatureVerificationFailure)null);
                A.CallTo(() => _allHeadersPresentVerificationTask.Verify(A <HttpRequestForSigning> ._, A <Signature> ._, A <Client> ._)).Returns((SignatureVerificationFailure)null);
                A.CallTo(() => _creationTimeVerificationTask.Verify(A <HttpRequestForSigning> ._, A <Signature> ._, A <Client> ._)).Returns((SignatureVerificationFailure)null);
                A.CallTo(() => _expirationTimeVerificationTask.Verify(A <HttpRequestForSigning> ._, A <Signature> ._, A <Client> ._)).Returns((SignatureVerificationFailure)null);
                A.CallTo(() => _nonceVerificationTask.Verify(A <HttpRequestForSigning> ._, A <Signature> ._, A <Client> ._)).Returns((SignatureVerificationFailure)null);
                A.CallTo(() => _digestVerificationTask.Verify(A <HttpRequestForSigning> ._, A <Signature> ._, A <Client> ._)).Returns((SignatureVerificationFailure)null);
                A.CallTo(() => _matchingSignatureStringVerificationTask.Verify(A <HttpRequestForSigning> ._, A <Signature> ._, A <Client> ._)).Returns((SignatureVerificationFailure)null);

                _sanitizedSignature = (Signature)_signature.Clone();
                A.CallTo(() => _signatureSanitizer.Sanitize(_signature, _client))
                .Returns(_sanitizedSignature);
            }
        public override SignatureVerificationFailure VerifySync(HttpRequestForSigning signedRequest, Signature signature, Client client)
        {
            if (!signature.Headers.Contains(HeaderName.PredefinedHeaderNames.RequestTarget))
            {
                return(SignatureVerificationFailure.HeaderMissing($"The {HeaderName.PredefinedHeaderNames.RequestTarget} header is required to be included in the signature."));
            }

            if (client.SignatureAlgorithm.ShouldIncludeDateHeader() && !signature.Headers.Contains(HeaderName.PredefinedHeaderNames.Date))
            {
                return(SignatureVerificationFailure.HeaderMissing($"The inclusion of the {HeaderName.PredefinedHeaderNames.Date} header is required when using security algorithm '{client.SignatureAlgorithm.Name}'."));
            }

            if (client.SignatureAlgorithm.ShouldIncludeCreatedHeader() && !signature.Headers.Contains(HeaderName.PredefinedHeaderNames.Created))
            {
                return(SignatureVerificationFailure.HeaderMissing($"The inclusion of the {HeaderName.PredefinedHeaderNames.Created} header is required when using security algorithm '{client.SignatureAlgorithm.Name}'."));
            }

            if (client.SignatureAlgorithm.ShouldIncludeExpiresHeader() && !signature.Headers.Contains(HeaderName.PredefinedHeaderNames.Expires))
            {
                return(SignatureVerificationFailure.HeaderMissing($"The inclusion of the {HeaderName.PredefinedHeaderNames.Expires} header is required when using security algorithm '{client.SignatureAlgorithm.Name}'."));
            }

            foreach (var headerName in signature.Headers)
            {
                if (headerName != HeaderName.PredefinedHeaderNames.RequestTarget)
                {
                    if (!signedRequest.Headers.Contains(headerName))
                    {
                        return(SignatureVerificationFailure.HeaderMissing($"The request header {headerName} is missing, but it is required to validate the signature."));
                    }
                }
            }

            return(null);
        }
예제 #5
0
        public string Compose(HttpRequestForSigning request, string signatureAlgorithmName, HeaderName[] headerNames, DateTimeOffset timeOfComposing, TimeSpan expires, string nonce)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }
            if (signatureAlgorithmName == null)
            {
                throw new ArgumentNullException(nameof(signatureAlgorithmName));
            }
            if (headerNames == null)
            {
                throw new ArgumentNullException(nameof(headerNames));
            }

            var headerAppender = _headerAppenderFactory.Create(request, signatureAlgorithmName, timeOfComposing, expires);

            var sb = new StringBuilder();

            foreach (var headerName in headerNames.Where(h => h != HeaderName.Empty))
            {
                sb = sb.Append(headerAppender.BuildStringToAppend(headerName));
            }

            sb.Append(_nonceAppender.BuildStringToAppend(nonce));

            return(sb.ToString().Trim());
        }
        public async Task <SignatureVerificationFailure> VerifySignature(HttpRequestForSigning signedRequest, Signature signature, Client client)
        {
            if (signedRequest == null)
            {
                throw new ArgumentNullException(nameof(signedRequest));
            }
            if (signature == null)
            {
                throw new ArgumentNullException(nameof(signature));
            }
            if (client == null)
            {
                throw new ArgumentNullException(nameof(client));
            }

            var sanitizedSignature = await _signatureSanitizer.Sanitize(signature, client);

            var failure = await _knownAlgorithmVerificationTask.Verify(signedRequest, sanitizedSignature, client) ??
                          await _matchingAlgorithmVerificationTask.Verify(signedRequest, sanitizedSignature, client) ??
                          await _createdHeaderGuardVerificationTask.Verify(signedRequest, sanitizedSignature, client) ??
                          await _expiresHeaderGuardVerificationTask.Verify(signedRequest, sanitizedSignature, client) ??
                          await _allHeadersPresentVerificationTask.Verify(signedRequest, sanitizedSignature, client) ??
                          await _creationTimeVerificationTask.Verify(signedRequest, sanitizedSignature, client) ??
                          await _expirationTimeVerificationTask.Verify(signedRequest, sanitizedSignature, client) ??
                          await _nonceVerificationTask.Verify(signedRequest, sanitizedSignature, client) ??
                          await _digestVerificationTask.Verify(signedRequest, sanitizedSignature, client) ??
                          await _matchingSignatureStringVerificationTask.Verify(signedRequest, sanitizedSignature, client);

            return(failure);
        }
            public async Task CallsSigningStringComposerWithExpectedParameters()
            {
                HttpRequestForSigning interceptedRequest = null;
                string interceptedSignatureAlgorithmName = null;

                HeaderName[]   interceptedHeaderNames = null;
                DateTimeOffset?interceptedCreated     = null;
                TimeSpan?      interceptedExpires     = null;

                A.CallTo(() => _signingStringComposer.Compose(A <HttpRequestForSigning> ._, A <string> ._, A <HeaderName[]> ._, A <DateTimeOffset> ._, A <TimeSpan> ._, A <string> ._))
                .Invokes(call => {
                    interceptedRequest = call.GetArgument <HttpRequestForSigning>(0);
                    interceptedSignatureAlgorithmName = call.GetArgument <string>(1);
                    interceptedHeaderNames            = call.GetArgument <HeaderName[]>(2);
                    interceptedCreated = call.GetArgument <DateTimeOffset>(3);
                    interceptedExpires = call.GetArgument <TimeSpan>(4);
                })
                .Returns(_composedSignatureString);

                await _method(_signedRequest, _signature, _client);

                interceptedCreated.Should().Be(_signature.Created);
                interceptedSignatureAlgorithmName.Should().Be("TEST");
                interceptedExpires.Should().Be(_signature.Expires.Value - _signature.Created.Value);
                interceptedRequest.Should().Be(_signedRequest);
                interceptedHeaderNames.Should().Equal(_signature.Headers);
            }
 public Verify()
 {
     _signature     = (Signature)TestModels.Signature.Clone();
     _signedRequest = (HttpRequestForSigning)TestModels.Request.Clone();
     _client        = new Client(TestModels.Client.Id, TestModels.Client.Name, new HMACSignatureAlgorithm("s3cr3t", HashAlgorithmName.MD5), TimeSpan.FromMinutes(1));
     _method        = (request, signature, client) => _sut.Verify(request, signature, client);
 }
예제 #9
0
 public Verify()
 {
     _signature     = (Signature)TestModels.Signature.Clone();
     _signedRequest = (HttpRequestForSigning)TestModels.Request.Clone();
     _client        = (Client)TestModels.Client.Clone();
     _method        = (request, signature, client) => _sut.Verify(request, signature, client);
 }
예제 #10
0
        internal static HttpRequestForSigning ToHttpRequestForSigning(this IOwinRequest owinRequest)
        {
            var request = new HttpRequestForSigning {
                Method     = new HttpMethod(owinRequest.Method),
                RequestUri = (owinRequest.Uri.IsAbsoluteUri ? owinRequest.Uri.AbsolutePath : owinRequest.Uri.OriginalString.Split('?')[0]).UrlDecode()
            };

            foreach (var header in owinRequest.Headers)
            {
                request.Headers[header.Key] = header.Value;
            }

            if (ShouldReadBody(owinRequest) && owinRequest.Body != null)
            {
                using (var memoryStream = new MemoryStream()) {
                    owinRequest.Body.CopyTo(memoryStream);
                    request.Body = memoryStream.ToArray();

                    owinRequest.Body?.Dispose();
                    owinRequest.Body = new MemoryStream(request.Body);
                }
            }

            return(request);
        }
예제 #11
0
        public override SignatureVerificationFailure VerifySync(HttpRequestForSigning signedRequest, Signature signature, Client client)
        {
            var expires = signature.Created.HasValue && signature.Expires.HasValue
                ? signature.Expires.Value - signature.Created.Value
                : new TimeSpan?();

            var signingString = _signingStringComposer.Compose(
                signedRequest,
                signature.Headers,
                signature.Created,
                expires,
                signature.Nonce);

            _logger?.LogDebug("Composed the following signing string for request verification: {0}", signingString);

            byte[] receivedSignature;
            try {
                receivedSignature = _base64Converter.FromBase64(signature.String);
            }
            catch (FormatException ex) {
                return(SignatureVerificationFailure.InvalidSignatureString(ex.Message, ex));
            }

            var isValidSignature = client.SignatureAlgorithm.VerifySignature(signingString, receivedSignature);

            _logger?.LogDebug("The verification of the signature {0}.", isValidSignature ? "succeeded" : "failed");

            if (!isValidSignature)
            {
                return(SignatureVerificationFailure.InvalidSignatureString("The signature string does not match the expected value."));
            }

            return(null);
        }
 public DefaultHeaderAppenderTests()
 {
     _httpRequest = new HttpRequestForSigning {
         Method     = HttpMethod.Post,
         RequestUri = "http://dalion.eu/api/resource/id1"
     };
     _sut = new DefaultHeaderAppender(_httpRequest);
 }
예제 #13
0
 public Verify()
 {
     _signature         = (Signature)TestModels.Signature.Clone();
     _signature.Headers = _signature.Headers.Concat(new[] { HeaderName.PredefinedHeaderNames.Expires }).ToArray();
     _signedRequest     = (HttpRequestForSigning)TestModels.Request.Clone();
     _client            = new Client(TestModels.Client.Id, TestModels.Client.Name, new CustomSignatureAlgorithm("RSA"), TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1));
     _method            = (request, signature, client) => _sut.Verify(request, signature, client);
 }
 public RequestTargetHeaderAppenderTests()
 {
     _httpRequest = new HttpRequestForSigning {
         Method     = HttpMethod.Post,
         RequestUri = "/api/resource/id1"
     };
     _sut = new RequestTargetHeaderAppender(_httpRequest);
 }
 public Create()
 {
     _timeOfComposing = new DateTimeOffset(2020, 2, 24, 11, 20, 14, TimeSpan.FromHours(1));
     _expires         = TimeSpan.FromMinutes(5);
     _httpRequest     = new HttpRequestForSigning {
         Method     = HttpMethod.Post,
         RequestUri = "http://dalion.eu/api/resource/id1"
     };
 }
예제 #16
0
 public Verify()
 {
     _signature           = (Signature)TestModels.Signature.Clone();
     _signature.Algorithm = "hmac-sha256";
     _signature.Headers   = _signature.Headers.Concat(new[] { HeaderName.PredefinedHeaderNames.Expires }).ToArray();
     _signedRequest       = (HttpRequestForSigning)TestModels.Request.Clone();
     _signedRequest.Headers.Add(HeaderName.PredefinedHeaderNames.Expires, _signature.Expires.Value.ToUnixTimeSeconds().ToString());
     _client = new Client(TestModels.Client.Id, TestModels.Client.Name, new CustomSignatureAlgorithm("hs2019"), TimeSpan.FromMinutes(1));
     _method = (request, signature, client) => _sut.Verify(request, signature, client);
 }
            public Verify()
            {
                _signature     = (Signature)TestModels.Signature.Clone();
                _signedRequest = (HttpRequestForSigning)TestModels.Request.Clone();
                _client        = (Client)TestModels.Client.Clone();
                _method        = (request, signature, client) => _sut.Verify(request, signature, client);

                _now = _signature.Created.Value.AddSeconds(3);
                A.CallTo(() => _systemClock.UtcNow).Returns(_now);
            }
            public Verify()
            {
                _signature     = (Signature)TestModels.Signature.Clone();
                _signedRequest = (HttpRequestForSigning)TestModels.Request.Clone();
                _client        = (Client)TestModels.Client.Clone();
                _method        = (request, signature, client) => _sut.Verify(request, signature, client);

                _now = new DateTimeOffset(2020, 3, 20, 11, 52, 23, TimeSpan.Zero);
                A.CallTo(() => _systemClock.UtcNow).Returns(_now);
            }
예제 #19
0
        public override SignatureVerificationFailure VerifySync(HttpRequestForSigning signedRequest, Signature signature, Client client)
        {
            if (
                signature.Headers.Contains(HeaderName.PredefinedHeaderNames.Created) &&
                AlgorithmNamesThatDoNotAllowCreatedValue.Any(alg => signature.Algorithm.StartsWith(alg, StringComparison.OrdinalIgnoreCase)))
            {
                return(SignatureVerificationFailure.InvalidCreatedHeader(
                           $"It is not allowed to take the {HeaderName.PredefinedHeaderNames.Created} into account, when the signature algorithm is {signature.Algorithm}."));
            }

            return(null);
        }
            public Verify()
            {
                _signature          = (Signature)TestModels.Signature.Clone();
                _signedRequest      = (HttpRequestForSigning)TestModels.Request.Clone();
                _signatureAlgorithm = new CustomSignatureAlgorithm("TEST");
                _client             = new Client(TestModels.Client.Id, TestModels.Client.Name, _signatureAlgorithm, TimeSpan.FromMinutes(1));
                _method             = (request, signature, client) => _sut.Verify(request, signature, client);

                _composedSignatureString = "abc123";
                A.CallTo(() => _signingStringComposer.Compose(A <HttpRequestForSigning> ._, A <string> ._, A <HeaderName[]> ._, A <DateTimeOffset> ._, A <TimeSpan> ._, A <string> ._))
                .Returns(_composedSignatureString);
                _signature.String = _base64Converter.ToBase64(_client.SignatureAlgorithm.ComputeHash(_composedSignatureString));
            }
        public IHeaderAppender Create(HttpRequestForSigning request, DateTimeOffset?timeOfComposing, TimeSpan?expires)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            return(new CompositeHeaderAppender(
                       new DefaultHeaderAppender(request),
                       new RequestTargetHeaderAppender(request),
                       new CreatedHeaderAppender(timeOfComposing),
                       new ExpiresHeaderAppender(timeOfComposing, expires),
                       new DateHeaderAppender(request)));
        }
예제 #22
0
        public override SignatureVerificationFailure VerifySync(HttpRequestForSigning signedRequest, Signature signature, Client client)
        {
            if (signature.Headers.Contains(HeaderName.PredefinedHeaderNames.Expires) && !signature.Expires.HasValue)
            {
                return(SignatureVerificationFailure.HeaderMissing($"The signature does not contain a value for the {nameof(signature.Expires)} property, but it is required."));
            }

            if (signature.Expires.HasValue && signature.Expires.Value < _systemClock.UtcNow.Add(-client.ClockSkew))
            {
                return(SignatureVerificationFailure.SignatureExpired("The signature is expired."));
            }

            return(null);
        }
예제 #23
0
        public override SignatureVerificationFailure VerifySync(HttpRequestForSigning signedRequest, Signature signature, Client client)
        {
            if (signature.Headers.Contains(HeaderName.PredefinedHeaderNames.Created) && !signature.Created.HasValue)
            {
                return(SignatureVerificationFailure.InvalidCreatedHeader($"The signature does not contain a value for the {nameof(signature.Created)} property, but it is required."));
            }

            if (signature.Created.HasValue && signature.Created.Value > _systemClock.UtcNow.Add(client.ClockSkew))
            {
                return(SignatureVerificationFailure.InvalidCreatedHeader("The signature is not valid yet. Its creation time is in the future."));
            }

            return(null);
        }
예제 #24
0
        public override SignatureVerificationFailure VerifySync(HttpRequestForSigning signedRequest, Signature signature, Client client)
        {
            // Algorithm parameter is not required
            if (string.IsNullOrEmpty(signature.Algorithm))
            {
                _logger?.LogDebug("Algorithm verification is not required, because there is no algorithm specified in the signature.");
                return(null);
            }

            // hs2019 is always allowed
            if (signature.Algorithm == Signature.DefaultSignatureAlgorithm)
            {
                return(null);
            }

            var algorithmParts = new List <string>();

            if (!string.IsNullOrEmpty(signature.Algorithm))
            {
                var separatorIndex = signature.Algorithm.IndexOf('-');
                if (separatorIndex < 0 || separatorIndex >= signature.Algorithm.Length - 1)
                {
                    algorithmParts.Add(signature.Algorithm);
                }
                else
                {
                    algorithmParts.Add(signature.Algorithm.Substring(0, separatorIndex));
                    algorithmParts.Add(signature.Algorithm.Substring(separatorIndex + 1));
                }
            }

            if (algorithmParts.Count < 2)
            {
                return(SignatureVerificationFailure.InvalidSignatureAlgorithm($"The specified signature algorithm ({signature.Algorithm}) is not supported."));
            }

            if (!SupportedSignatureAlgorithmNames.Contains(algorithmParts[0]))
            {
                return(SignatureVerificationFailure.InvalidSignatureAlgorithm($"The specified signature algorithm ({signature.Algorithm}) is not supported."));
            }

            if (!SupportedHashAlgorithmNames.Contains(algorithmParts[1].ToUpperInvariant()))
            {
                return(SignatureVerificationFailure.InvalidSignatureAlgorithm($"The specified hash algorithm ({algorithmParts[1]}) is not supported."));
            }

            return(null);
        }
        public override SignatureVerificationFailure VerifySync(HttpRequestForSigning signedRequest, Signature signature, Client client)
        {
            // Algorithm parameter is not required
            if (string.IsNullOrEmpty(signature.Algorithm))
            {
                _logger?.LogDebug("Algorithm match verification is not required, because there is no algorithm specified in the signature.");
                return(null);
            }

            // hs2019 is always ok
            if (signature.Algorithm == Signature.DefaultSignatureAlgorithm)
            {
                return(null);
            }

            var algorithmParts = new List <string>();

            if (!string.IsNullOrEmpty(signature.Algorithm))
            {
                var separatorIndex = signature.Algorithm.IndexOf('-');
                if (separatorIndex < 0 || separatorIndex >= signature.Algorithm.Length - 1)
                {
                    algorithmParts.Add(signature.Algorithm);
                }
                else
                {
                    algorithmParts.Add(signature.Algorithm.Substring(0, separatorIndex));
                    algorithmParts.Add(signature.Algorithm.Substring(separatorIndex + 1));
                }
            }

            if (algorithmParts.Count < 2)
            {
                return(SignatureVerificationFailure.InvalidSignatureAlgorithm($"The specified signature algorithm ({signature.Algorithm}) is not supported."));
            }

            if (!client.SignatureAlgorithm.Name.Equals(algorithmParts[0], StringComparison.OrdinalIgnoreCase))
            {
                return(SignatureVerificationFailure.InvalidSignatureAlgorithm($"The specified signature algorithm ({algorithmParts[0]}) does not match the registered signature algorithm for the client with id {client.Id}."));
            }

            if (!client.SignatureAlgorithm.HashAlgorithm.Name.Equals(algorithmParts[1], StringComparison.OrdinalIgnoreCase))
            {
                return(SignatureVerificationFailure.InvalidSignatureAlgorithm($"The specified hash algorithm ({algorithmParts[1]}) does not match the registered hash algorithm for the client with id {client.Id}."));
            }

            return(null);
        }
예제 #26
0
            public Verify()
            {
                _signature     = (Signature)TestModels.Signature.Clone();
                _signedRequest = (HttpRequestForSigning)TestModels.Request.Clone();
                _client        = (Client)TestModels.Client.Clone();
                _method        = (request, signature, client) => _sut.Verify(request, signature, client);

                _signedRequest.Body = Encoding.UTF8.GetBytes("I am the body payload");
                using (var hashAlgorithm = HashAlgorithm.Create("SHA-384")) {
                    var digestBytes  = hashAlgorithm.ComputeHash(_signedRequest.Body);
                    var digestString = new Base64Converter().ToBase64(digestBytes);
                    _signedRequest.Headers.Add(HeaderName.PredefinedHeaderNames.Digest, "SHA-384=" + digestString);
                }

                _signature.Headers = _signature.Headers.Concat(new[] { HeaderName.PredefinedHeaderNames.Digest }).ToArray();
            }
예제 #27
0
        public IHeaderAppender Create(HttpRequestForSigning request, string signatureAlgorithmName, DateTimeOffset timeOfComposing, TimeSpan expires)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }
            if (signatureAlgorithmName == null)
            {
                throw new ArgumentNullException(nameof(signatureAlgorithmName));
            }

            return(new CompositeHeaderAppender(
                       new DefaultHeaderAppender(request),
                       new RequestTargetHeaderAppender(request),
                       new CreatedHeaderAppender(signatureAlgorithmName, timeOfComposing),
                       new ExpiresHeaderAppender(signatureAlgorithmName, timeOfComposing, expires),
                       new DateHeaderAppender(request)));
        }
            public Compose()
            {
                _timeOfComposing = new DateTimeOffset(2020, 2, 24, 11, 20, 14, TimeSpan.FromHours(1));
                _expires         = TimeSpan.FromMinutes(5);
                _httpRequest     = new HttpRequestForSigning {
                    Method     = HttpMethod.Post,
                    RequestUri = "http://dalion.eu/api/resource/id1"
                };
                _headerNames = new[] {
                    HeaderName.PredefinedHeaderNames.RequestTarget,
                    HeaderName.PredefinedHeaderNames.Date,
                    new HeaderName("dalion_app_id")
                };
                _nonce = "abc123";

                FakeFactory.Create(out _headerAppender);
                A.CallTo(() => _headerAppenderFactory.Create(_httpRequest, _timeOfComposing, _expires))
                .Returns(_headerAppender);
            }
        internal static async Task <HttpRequestForSigning> ToRequestForSigning(this HttpRequest request, Signature signature)
        {
            if (signature == null)
            {
                throw new ArgumentNullException(nameof(signature));
            }
            if (request == null)
            {
                return(null);
            }

            var requestMessage = new HttpRequestForSigning {
                RequestUri = GetRequestUri(request),
                Method     = string.IsNullOrEmpty(request.Method)
                    ? HttpMethod.Get
                    : new HttpMethod(request.Method)
            };

            foreach (var header in request.Headers)
            {
                requestMessage.Headers[header.Key] = new StringValues((string[])header.Value);
            }

            if (ShouldReadBody(request, signature) && request.Body != null)
            {
                request.EnableBuffering();

                // ReSharper disable once UseAwaitUsing
                // ReSharper disable once ConvertToUsingDeclaration
                using (var memoryStream = new MemoryStream()) {
                    await request.Body.CopyToAsync(memoryStream);

                    requestMessage.Body = memoryStream.ToArray();
                    request.Body.Seek(0, SeekOrigin.Begin);
                }
            }

            return(requestMessage);
        }
예제 #30
0
        public override async Task <SignatureVerificationFailure> Verify(HttpRequestForSigning signedRequest, Signature signature, Client client)
        {
            if (string.IsNullOrEmpty(signature.Nonce))
            {
                return(null);
            }

            var previousNonce = await _nonceStore.Get(client.Id, signature.Nonce).ConfigureAwait(false);

            if (previousNonce != null && previousNonce.Expiration >= _systemClock.UtcNow)
            {
                return(SignatureVerificationFailure.ReplayedRequest($"The nonce '{previousNonce.Value}' for client {client.Id} ({client.Name}) is not unique and has been used before. It expires at {previousNonce.Expiration:R}."));
            }

            var nonce = new Nonce(
                clientId: client.Id,
                value: signature.Nonce,
                expiration: _systemClock.UtcNow.Add(client.NonceLifetime));
            await _nonceStore.Register(nonce).ConfigureAwait(false);

            return(null);
        }