public async Task ValidateBewit_WithAlteredPayload_ShouldThrow()
        {
            //Arrange
            ICryptographyService cryptoService =
                MockHelper.GetMockedCrpytoService <Foo>();
            var nonceRepository = new DefaultNonceRepository();
            var provider        =
                new BewitTokenValidatorAccessor <Foo>(
                    cryptoService, new MockHelper.MockedVariablesProvider(), nonceRepository);

            var bewit = new Bewit <Foo>(
                "724e7acc-be57-49a1-8195-46a03c6271c6",
                new DateTime(2017, 1, 1, 1, 2, 1, 1, DateTimeKind.Utc),
                new Foo
            {
                Bar = 2
            },
                "724e7acc-be57-49a1-8195-46a03c6271c6__2017-01-01T01:02:01.0010000Z__{\"Bar\":1}");
            await nonceRepository.InsertOneAsync(bewit, default);

            //Act
            Func <Task> validateBewit = async() =>
                                        await provider.InvokeValidateBewitAsync(bewit,
                                                                                CancellationToken.None);

            //Assert
            await validateBewit.Should().ThrowAsync <BewitInvalidException>();
        }
        public async Task ValidateBewit_WithPayload_ShouldGenerateBewit()
        {
            //Arrange
            ICryptographyService cryptoService =
                MockHelper.GetMockedCrpytoService <Foo>();
            var nonceRepository = new DefaultNonceRepository();
            var provider        =
                new BewitTokenValidatorAccessor <Foo>(
                    cryptoService, new MockHelper.MockedVariablesProvider(), nonceRepository);
            var payload = new Foo
            {
                Bar = 1
            };

            var bewit = new Bewit <Foo>(
                "724e7acc-be57-49a1-8195-46a03c6271c6",
                new DateTime(2017, 1, 1, 1, 2, 1, 1, DateTimeKind.Utc),
                payload,
                "724e7acc-be57-49a1-8195-46a03c6271c6__2017-01-01T01:02:01.0010000Z__{\"Bar\":1}");
            await nonceRepository.InsertOneAsync(bewit, default);

            //Act
            Bewit <Foo> bewit2 = await provider.InvokeValidateBewitAsync(bewit, CancellationToken.None);

            //Assert
            bewit2.Should().Be(bewit);
        }
        public async Task ValidateBewitToken_WithPayload_ShouldReturnPayload()
        {
            //Arrange
            ICryptographyService cryptoService =
                MockHelper.GetMockedCrpytoService <Foo>();
            var nonceRepository         = new DefaultNonceRepository();
            BewitPayloadContext context = new BewitPayloadContext(typeof(Foo))
                                          .SetCryptographyService(() => cryptoService)
                                          .SetVariablesProvider(() => new MockHelper.MockedVariablesProvider())
                                          .SetRepository(() => nonceRepository);
            var provider = new BewitTokenValidator <Foo>(context);
            var payload  = new Foo
            {
                Bar = 1
            };
            var bewit = new Bewit <Foo>(
                "724e7acc-be57-49a1-8195-46a03c6271c6",
                new DateTime(2016, 1, 1, 1, 1, 1, 1, DateTimeKind.Utc),
                payload,
                "724e7acc-be57-49a1-8195-46a03c6271c6__2016-01-01T01:01:01.0010000Z__{\"Bar\":1}");
            await nonceRepository.InsertOneAsync(bewit, default);

            var bewitToken = new BewitToken <Foo>(
                "eyJQYXlsb2FkIjp7IkJhciI6MX0sIkhhc2giOiI3MjRlN2FjYy1iZTU3LTQ5YTEtODE5NS00NmEwM2M2MjcxYzZfXzIwMTctMDEtMDFUMDE6MDI6MDEuMDAxMDAwMFpfX3tcIkJhclwiOjF9IiwiTm9uY2UiOiI3MjRlN2FjYy1iZTU3LTQ5YTEtODE5NS00NmEwM2M2MjcxYzYiLCJFeHBpcmF0aW9uRGF0ZSI6IjIwMTctMDEtMDFUMDE6MDI6MDEuMDAxWiJ9");

            //Act
            Foo payload2 =
                await provider.ValidateBewitTokenAsync(bewitToken, CancellationToken.None);

            //Assert
            payload2.Bar.Should().Be(payload.Bar);
        }
Пример #4
0
        public async Task FindOneAndDeleteAsync_WithExistingNonceDerivate_ShouldRetrieveAndDeleteNonce()
        {
            //Arrange
            IMongoDatabase           database       = _mongoResource.CreateDatabase();
            var                      repository     = new MongoNonceRepository(database, new MongoNonceOptions());
            var                      token          = "myToken";
            DateTime                 expirationDate = DateTime.UtcNow;
            var                      nonce          = new Bewit <Bar>(token, expirationDate, new Bar(), "hash");
            IMongoCollection <Token> collection     = database.GetCollection <Token>(nameof(Token));
            await collection.InsertOneAsync(
                nonce, new InsertOneOptions(), CancellationToken.None);

            //Act
            Token returnedNonce =
                await repository.TakeOneAsync(token,
                                              CancellationToken.None);

            //Assert
            var items = (
                await collection.FindAsync(
                    Builders <Token> .Filter.Empty,
                    cancellationToken: CancellationToken.None)
                ).ToList();

            items.Should().BeEmpty();
            returnedNonce.Nonce.Should().Be(token);
            returnedNonce.ExpirationDate.Date.Should().Be(expirationDate.Date);
        }
Пример #5
0
        public async Task GenerateBewitAsync_WithDifferentPayload_ShouldGenerateDifferentBewit()
        {
            //Arrange
            var variableProvider = new MockHelper.MockedVariablesProvider();
            var tokenTuration    = TimeSpan.FromMinutes(1);
            var provider         =
                new BewitTokenGeneratorAccessor <Foo>(
                    tokenTuration,
                    MockHelper.GetMockedCrpytoService <Foo>(),
                    variableProvider);
            var payload = new Foo
            {
                Bar = 5
            };

            //Act
            Bewit <Foo> bewit =
                await provider.InvokeGenerateBewitAsync(payload,
                                                        CancellationToken.None);

            //Assert
            bewit.Nonce.Should().Be(variableProvider.NextToken.ToString());
            bewit.ExpirationDate.Should()
            .Be(variableProvider.UtcNow.AddTicks(tokenTuration.Ticks));
            bewit.Payload.Should().BeEquivalentTo(payload);
            bewit.Hash.Should()
            .Be("724e7acc-be57-49a1-8195-46a03c6271c6__2017-01-01T01:02:01.0010000Z__{\"Bar\":5}");
        }
Пример #6
0
        protected async ValueTask <Bewit <T> > ValidateBewitAsync(
            Bewit <T> bewit,
            CancellationToken cancellationToken)
        {
            if (bewit is null)
            {
                throw new BewitNotFoundException();
            }

            if (bewit.ExpirationDate < _variablesProvider.UtcNow)
            {
                throw new BewitExpiredException();
            }

            var hashToMatch = _cryptographyService.GetHash(
                bewit.Nonce,
                bewit.ExpirationDate,
                bewit.Payload);

            if (!string.Equals(hashToMatch, bewit.Hash,
                               StringComparison.InvariantCulture))
            {
                throw new BewitInvalidException();
            }

            Token token = await _repository.TakeOneAsync(bewit.Nonce, cancellationToken);

            if (token != null)
            {
                return(bewit);
            }

            throw new BewitNotFoundException();
        }
Пример #7
0
        public async Task <T> ValidateBewitTokenAsync(
            BewitToken <T> bewit,
            CancellationToken cancellationToken)
        {
            Bewit <T> bewitInternal  = DeserializeBewitWithoutValidation(bewit);
            Bewit <T> validatedBewit = await ValidateBewitAsync(bewitInternal, cancellationToken);

            return(validatedBewit.Payload);
        }
Пример #8
0
        public async Task <BewitToken <T> > GenerateBewitTokenAsync(
            T payload,
            CancellationToken cancellationToken)
        {
            Bewit <T> bewit = await GenerateBewitAsync(payload, cancellationToken);

            // Refactor: TypeNameHandling.All
            var serializedBewit = JsonConvert.SerializeObject(bewit);
            var base64Bewit     = Convert.ToBase64String(Encoding.UTF8.GetBytes(serializedBewit));

            return(new BewitToken <T>(base64Bewit));
        }
Пример #9
0
        public async Task OnAuthorization_WithAlteredPayloadForUrl_ShouldNotAuthorize()
        {
            //Arrange
            var                 cryptoService = new HmacSha256CryptographyService(Options);
            TestServer          server        = TestServerHelper.CreateServer <string>(Options);
            var                 url           = "/api/dummy/SomeBewitProtectedUrl";
            BewitPayloadContext context       = new BewitPayloadContext(typeof(string))
                                                .SetCryptographyService(() => cryptoService)
                                                .SetVariablesProvider(() => TestServerHelper.VariablesProvider)
                                                .SetRepository(() => TestServerHelper.NonceRepository);
            var tokenGenerator             = new BewitTokenGenerator <string>(Options, context);
            BewitToken <string> bewitToken =
                await tokenGenerator.GenerateBewitTokenAsync(url.ToLowerInvariant(),
                                                             CancellationToken.None);

            //try to hack the token by replacing the url but reusing the same hash
            url = "/api/dummy/WithBewitProtection";
            var serializedBewit =
                Encoding.UTF8.GetString(Convert.FromBase64String((string)bewitToken));
            Bewit <string> bewitInternal =
                JsonConvert.DeserializeObject <Bewit <string> >(serializedBewit);
            var newBewitInternal = new Bewit <string>(
                bewitInternal.Nonce,
                bewitInternal.ExpirationDate,
                url.ToLowerInvariant(),
                bewitInternal.Hash);

            serializedBewit = JsonConvert.SerializeObject(newBewitInternal);
            bewitToken      = new BewitToken <string>(Convert.ToBase64String(
                                                          Encoding.UTF8.GetBytes(serializedBewit)
                                                          ));

            var        fullUrl = $"{url}?bewit={bewitToken}";
            HttpClient client  = server.CreateClient();

            //Act
            HttpResponseMessage res =
                await client.GetAsync(fullUrl, CancellationToken.None);

            //Assert
            res.StatusCode.Should().Be(HttpStatusCode.Forbidden);
            var content = await res.Content.ReadAsStringAsync();

            if (content != null)
            {
                Assert.Equal(-1, content.IndexOf("bar"));
            }
        }
Пример #10
0
        /// <summary>
        /// Adds the bewit to the query string of the specified HttpRequestMessage object and
        /// returns the bewit string.
        /// </summary>
        internal async Task <string> CreateBewitInternalAsync(HttpRequestMessage request, DateTime utcNow, int lifeSeconds)
        {
            var    bewit       = new Bewit(request, credentialFunc(), utcNow, lifeSeconds, this.ApplicationSpecificData);
            string bewitString = await bewit.ToBewitStringAsync();

            string parameter = String.Format("{0}={1}", HawkConstants.Bewit, bewitString);

            string queryString = request.RequestUri.Query;

            queryString = String.IsNullOrWhiteSpace(queryString) ? parameter : queryString.Substring(1) + "&" + parameter;

            var builder = new UriBuilder(request.RequestUri);

            builder.Query = queryString;

            request.RequestUri = builder.Uri;

            return(bewitString);
        }
Пример #11
0
        protected async ValueTask <Bewit <T> > GenerateBewitAsync(
            T payload,
            CancellationToken cancellationToken)
        {
            if (payload == null)
            {
                throw new ArgumentNullException(nameof(payload));
            }

            var      token          = _variablesProvider.NextToken.ToString("D", CultureInfo.InvariantCulture);
            DateTime expirationDate = _variablesProvider.UtcNow.AddTicks(_tokenDuration.Ticks);

            var hash  = _cryptographyService.GetHash(token, expirationDate, payload);
            var bewit = new Bewit <T>(token, expirationDate, payload, hash);

            await _repository.InsertOneAsync(bewit, cancellationToken);

            return(bewit);
        }
Пример #12
0
        public void Constructor_AllParamsSet_ShouldInitializeProperly()
        {
            //Arrange
            string   token          = "bar";
            DateTime expirationDate = DateTime.UtcNow;
            Foo      payload        = new Foo
            {
                Bar = 1
            };
            string hash = "123";

            //Act
            var bewit = new Bewit <Foo>(token, expirationDate, payload, hash);

            //Assert
            bewit.Should().NotBeNull();
            bewit.Nonce.Should().Be(token);
            bewit.ExpirationDate.Should().Be(expirationDate);
            bewit.Payload.Should().BeEquivalentTo(payload);
            bewit.Hash.Should().Be(hash);
        }
        /// <summary>
        /// Adds the bewit to the query string of the specified HttpRequestMessage object and
        /// returns the bewit string.
        /// </summary>
        internal string CreateBewitInternal(IRequestMessage request, DateTime utcNow, int lifeSeconds)
        {
            string appData = null;

            if (options.NormalizationCallback != null)
            {
                appData = options.NormalizationCallback(request);
            }

            var bewit = new Bewit(request, options.CredentialsCallback(),
                                  utcNow, lifeSeconds, appData, options.LocalTimeOffsetMillis);
            string bewitString = bewit.ToBewitString();

            string parameter = String.Format("{0}={1}", HawkConstants.Bewit, bewitString);

            string queryString = request.Uri.Query;

            queryString         = String.IsNullOrWhiteSpace(queryString) ? parameter : queryString.Substring(1) + "&" + parameter;
            request.QueryString = queryString;

            return(bewitString);
        }
Пример #14
0
        public async Task InsertOneAsync_WithNonceDerivate_ShouldStoreNonce()
        {
            //Arrange
            IMongoDatabase database       = _mongoResource.CreateDatabase();
            var            repository     = new MongoNonceRepository(database, new MongoNonceOptions());
            var            token          = "myToken";
            DateTime       expirationDate = DateTime.UtcNow;
            var            nonce          = new Bewit <Bar2 <int, string> >(token, expirationDate, new Bar2 <int, string>(), "hash");

            //Act
            await repository.InsertOneAsync(nonce, CancellationToken.None);

            //Assert
            IMongoCollection <Bewit <Bar2 <int, string> > > collection = database.GetCollection <Bewit <Bar2 <int, string> > >(nameof(Token));
            var items = (
                await collection.FindAsync(
                    Builders <Bewit <Bar2 <int, string> > > .Filter.Empty,
                    cancellationToken: CancellationToken.None)
                ).ToList();

            items.Should().ContainSingle();
            items.First().Nonce.Should().Be(token);
            items.First().ExpirationDate.Date.Should().Be(expirationDate.Date);
        }
        /// <summary>
        /// Adds the bewit to the query string of the specified HttpRequestMessage object and 
        /// returns the bewit string.
        /// </summary>
        internal async Task<string> CreateBewitInternalAsync(HttpRequestMessage request, DateTime utcNow, int lifeSeconds)
        {
            var bewit = new Bewit(request, credentialFunc(), utcNow, lifeSeconds, this.ApplicationSpecificData);
            string bewitString = await bewit.ToBewitStringAsync();

            string parameter = String.Format("{0}={1}", HawkConstants.Bewit, bewitString);

            string queryString = request.RequestUri.Query;
            queryString = String.IsNullOrWhiteSpace(queryString) ? parameter : queryString.Substring(1) + "&" + parameter;

            var builder = new UriBuilder(request.RequestUri);
            builder.Query = queryString;

            request.RequestUri = builder.Uri;

            return bewitString;
        }
 internal async ValueTask <Bewit <T> > InvokeValidateBewitAsync(
     Bewit <T> bewit,
     CancellationToken cancellationToken)
 {
     return(await ValidateBewitAsync(bewit, cancellationToken));
 }