Beispiel #1
0
        private static TestServer CreateTestServer()
        {
            IWebHostBuilder hostBuilder = new WebHostBuilder()
                                          .ConfigureServices(services =>
            {
                services.AddRouting();

                BewitPayloadContext context = new BewitPayloadContext(typeof(string))
                                              .SetCryptographyService(() => new HmacSha256CryptographyService(new BewitOptions {
                    Secret = "123"
                }))
                                              .SetVariablesProvider(() => new MockedVariablesProvider())
                                              .SetRepository(() => new DefaultNonceRepository());
                services.AddTransient <IBewitTokenGenerator <string> >(ctx =>
                                                                       new BewitTokenGenerator <string>(new BewitOptions(), context));
                services
                .AddGraphQLServer()
                .SetOptions(new SchemaOptions {
                    StrictValidation = false
                })
                .AddMutationType(d =>
                {
                    d.Name("Mutation");
                    d.Field("RequestAccess")
                    .Type <NonNullType <StringType> >()
                    .Resolver(ctx => "foo")
                    .UseBewitProtection <string>();
                });
            })
                                          .Configure(app =>
                                                     app.UseRouting().UseEndpoints(e => e.MapGraphQL("/")));

            return(new TestServer(hostBuilder));
        }
        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);
        }
Beispiel #3
0
        public async Task OnAuthorization_WithDifferentUrl_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);

            url = "/api/dummy/WithBewitProtection";
            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"));
            }
        }
Beispiel #4
0
        public static void UseMongoPersistence(
            this BewitPayloadContext context,
            IConfiguration configuration)
        {
            MongoNonceOptions options = configuration
                                        .GetSection("Bewit:Mongo")
                                        .Get <MongoNonceOptions>();

            context.UseMongoPersistence(options);
        }
Beispiel #5
0
        public BewitTokenValidator(BewitPayloadContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            _cryptographyService = context.CreateCryptographyService?.Invoke()
                                   ?? throw new ArgumentNullException(nameof(BewitPayloadContext.CreateCryptographyService));
            _variablesProvider = context.CreateVariablesProvider?.Invoke()
                                 ?? throw new ArgumentNullException(nameof(BewitPayloadContext.CreateVariablesProvider));
            _repository = context.CreateRepository?.Invoke()
                          ?? throw new ArgumentNullException(nameof(BewitPayloadContext.CreateRepository));
        }
Beispiel #6
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"));
            }
        }
Beispiel #7
0
        public void Constructor_WithAllMandatoryOptions_ShouldInit()
        {
            //Arrange
            ICryptographyService cryptoService =
                MockHelper.GetMockedCrpytoService <Foo>();
            BewitPayloadContext context = new BewitPayloadContext(typeof(string))
                                          .SetCryptographyService(() => cryptoService)
                                          .SetVariablesProvider(() => new MockHelper.MockedVariablesProvider())
                                          .SetRepository(() => new DefaultNonceRepository());

            //Act
            var provider = new BewitTokenGenerator <Foo>(new BewitOptions(), context);

            //Assert
            provider.Should().NotBeNull();
        }
Beispiel #8
0
        public static void UseMongoPersistence(
            this BewitPayloadContext context,
            MongoNonceOptions options)
        {
            options.Validate();

            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            context.SetRepository(() =>
            {
                var client = new MongoClient(options.ConnectionString);
                IMongoDatabase database = client.GetDatabase(options.DatabaseName);
                return(new MongoNonceRepository(database, options));
            });
        }
Beispiel #9
0
        public async Task ValidateBewitTokenAsync_WithLegitPayload_ShouldStoreNonceAndReturnBewitToken()
        {
            //Arrange
            Token insertedToken = Token.Create("724e7acc-be57-49a1-8195-46a03c6271c6", DateTime.MaxValue);
            var   repository    = new Mock <INonceRepository>();

            repository
            .Setup(r => r.TakeOneAsync(It.IsAny <string>(),
                                       It.IsAny <CancellationToken>()))
            .Returns((string tok, CancellationToken c) =>
            {
                if (tok == insertedToken.Nonce)
                {
                    Token tmpToken = insertedToken;
                    insertedToken  = null;
                    return(new ValueTask <Token>(tmpToken));
                }

                return(new ValueTask <Token>((Token)null));
            });
            BewitPayloadContext context = new BewitPayloadContext(typeof(Bar))
                                          .SetCryptographyService(MockHelper.GetMockedCrpytoService <Bar>)
                                          .SetVariablesProvider(() => new MockHelper.MockedVariablesProvider())
                                          .SetRepository(() => repository.Object);
            var provider =
                new BewitTokenValidator <Bar>(context);
            var payload = new Bar
            {
                Baz = "foo"
            };

            BewitToken <Bar> token = new BewitToken <Bar>("eyJQYXlsb2FkIjp7IkJheiI6ImZvbyJ9LCJIYXNoIjoiNzI0ZTdhY2MtYmU1Ny00OWExLTgxOTUtNDZhMDNjNjI3MWM2X18yMDE3LTAxLTAxVDAxOjAyOjAxLjAwMTAwMDBaX197XCJCYXpcIjpcImZvb1wifSIsIk5vbmNlIjoiNzI0ZTdhY2MtYmU1Ny00OWExLTgxOTUtNDZhMDNjNjI3MWM2IiwiRXhwaXJhdGlvbkRhdGUiOiIyMDE3LTAxLTAxVDAxOjAyOjAxLjAwMVoifQ==");

            //Act
            Bar payload2 =
                await provider.ValidateBewitTokenAsync(
                    token,
                    CancellationToken.None);

            //Assert
            payload2.Should().NotBeNull();
            payload2.Should().NotBe(payload);
            payload2.Should().BeEquivalentTo(payload);
        }
Beispiel #10
0
        public void UseMongoPersistence_WithBuilderNull_ShouldThrowArgumentNullException()
        {
            //Arrange
            BewitPayloadContext    context    = null;
            IMongoCollection <Foo> collection = _mongoResource.CreateCollection <Foo>();

            //Act
            Action useRepository = ()
                                   => context.UseMongoPersistence(
                new MongoNonceOptions
            {
                ConnectionString = _mongoResource.ConnectionString,
                DatabaseName     = collection.Database.DatabaseNamespace.DatabaseName
            }
                );

            //Assert
            useRepository.Should().Throw <ArgumentNullException>();
        }
Beispiel #11
0
        public void UseMongoPersistence_WithOnlyMandatoryParameters_ShouldInitAndReturnMongoNonceRepository()
        {
            //Arrange
            var builder = new BewitPayloadContext(typeof(object));
            IMongoCollection <Foo> collection = _mongoResource.CreateCollection <Foo>();

            //Act
            builder.UseMongoPersistence(
                new MongoNonceOptions
            {
                ConnectionString = _mongoResource.ConnectionString,
                DatabaseName     = collection.Database.DatabaseNamespace.DatabaseName
            }
                );

            //Assert
            builder.Should().Be(builder);
            builder.CreateRepository.Should().NotBeNull();
        }
Beispiel #12
0
        public void GenerateBewitTokenAsync_WithNullPayload_ShouldThrow()
        {
            //Arrange
            ICryptographyService cryptoService =
                MockHelper.GetMockedCrpytoService <Foo>();
            BewitPayloadContext context = new BewitPayloadContext(typeof(string))
                                          .SetCryptographyService(() => cryptoService)
                                          .SetVariablesProvider(() => new MockHelper.MockedVariablesProvider())
                                          .SetRepository(() => new DefaultNonceRepository());
            var provider = new BewitTokenGenerator <Foo>(new BewitOptions(), context);

            //Act
            Func <Task> generateBewit = async() =>
                                        await provider.GenerateBewitTokenAsync(null,
                                                                               CancellationToken.None);

            //Assert
            generateBewit.Should().Throw <ArgumentNullException>();
        }
Beispiel #13
0
        public void UseMongoPersistence_WithMissingDatabaseNameInConfiguration_ShouldInitAndReturnMongoNonceRepository()
        {
            //Arrange
            var builder = new BewitPayloadContext(typeof(object));
            IMongoCollection <Foo> collection    = _mongoResource.CreateCollection <Foo>();
            IConfiguration         configuration = new ConfigurationBuilder()
                                                   .AddInMemoryCollection(new[]
            {
                new KeyValuePair <string, string>("Bewit:Mongo:ConnectionString",
                                                  _mongoResource.ConnectionString),
                new KeyValuePair <string, string>("Bewit:Mongo:sefef",
                                                  collection.Database.DatabaseNamespace.DatabaseName),
            })
                                                   .Build();

            //Act
            Action builder2 = () => builder.UseMongoPersistence(configuration);

            //Assert
            builder2.Should().Throw <ArgumentException>();
        }
Beispiel #14
0
        public BewitTokenGenerator(
            BewitOptions options,
            BewitPayloadContext context)
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            _tokenDuration       = options.TokenDuration;
            _cryptographyService = context.CreateCryptographyService?.Invoke()
                                   ?? throw new ArgumentNullException(nameof(BewitPayloadContext.CreateCryptographyService));
            _variablesProvider = context.CreateVariablesProvider?.Invoke()
                                 ?? throw new ArgumentNullException(nameof(BewitPayloadContext.CreateVariablesProvider));
            _repository = context.CreateRepository?.Invoke()
                          ?? throw new ArgumentNullException(nameof(BewitPayloadContext.CreateRepository));
        }
Beispiel #15
0
        public void UseMongoPersistence_WithValidConfiguration_ShouldInitAndReturnMongoNonceRepository()
        {
            //Arrange
            var builder = new BewitPayloadContext(typeof(object));
            IMongoCollection <Foo> collection    = _mongoResource.CreateCollection <Foo>();
            IConfiguration         configuration = new ConfigurationBuilder()
                                                   .AddInMemoryCollection(new[]
            {
                new KeyValuePair <string, string>("Bewit:Mongo:ConnectionString",
                                                  _mongoResource.ConnectionString),
                new KeyValuePair <string, string>("Bewit:Mongo:DatabaseName",
                                                  collection.Database.DatabaseNamespace.DatabaseName),
            })
                                                   .Build();

            //Act
            builder.UseMongoPersistence(configuration);

            //Assert
            builder.Should().Be(builder);
            builder.CreateRepository.Should().NotBeNull();
        }
Beispiel #16
0
        public async Task GenerateBewitTokenAsync_WithDifferentPayload_ShouldGenerateBewit()
        {
            //Arrange
            ICryptographyService cryptoService = MockHelper.GetMockedCrpytoService <Foo>();
            BewitPayloadContext  context       = new BewitPayloadContext(typeof(string))
                                                 .SetCryptographyService(() => cryptoService)
                                                 .SetVariablesProvider(() => new MockHelper.MockedVariablesProvider())
                                                 .SetRepository(() => new DefaultNonceRepository());
            var provider = new BewitTokenGenerator <Foo>(new BewitOptions(), context);
            var payload  = new Foo
            {
                Bar = 5
            };

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

            //Assert
            ((string)bewit).Should().Be("eyJQYXlsb2FkIjp7IkJhciI6NX0sIkhhc2giOiI3MjRlN2FjYy1iZTU3LTQ5YTEtODE5NS00NmEwM2M2MjcxYzZfXzIwMTctMDEtMDFUMDE6MDI6MDEuMDAxMDAwMFpfX3tcIkJhclwiOjV9IiwiTm9uY2UiOiI3MjRlN2FjYy1iZTU3LTQ5YTEtODE5NS00NmEwM2M2MjcxYzYiLCJFeHBpcmF0aW9uRGF0ZSI6IjIwMTctMDEtMDFUMDE6MDI6MDEuMDAxWiJ9");
        }
        public async Task OnAuthorization_WithValidBewitForUrl_ShouldAuthorize()
        {
            //Arrange
            TestServer          server  = TestServerHelper.CreateServer <IDictionary <string, object> >(Options);
            BewitPayloadContext context = new BewitPayloadContext(typeof(IDictionary <string, object>))
                                          .SetCryptographyService(() => new HmacSha256CryptographyService(Options))
                                          .SetVariablesProvider(() => TestServerHelper.VariablesProvider)
                                          .SetRepository(() => TestServerHelper.NonceRepository);
            var          tokenGenerator = new BewitTokenGenerator <IDictionary <string, object> >(Options, context);
            const string id             = "1",
                         firstName      = "John",
                         lastName       = "Smith";
            var payload =
                new Dictionary <string, object>
            {
                ["firstName"] = "John",
                ["lastName"]  = "Smith"
            };
            BewitToken <IDictionary <string, object> > bewitToken =
                await tokenGenerator.GenerateBewitTokenAsync(
                    payload,
                    CancellationToken.None);

            var        url     = $"/api/dummy/WithBewitParameters/{id}";
            var        fullUrl = $"{url}?bewit={bewitToken}";
            HttpClient client  = server.CreateClient();

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

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

            content.Should().Be($"{id}: {firstName} {lastName}");
        }