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); }
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); }
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}"); }
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(); }
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); }
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)); }
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")); } }
/// <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); }
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); }
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); }
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)); }