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);
        }
Esempio n. 2
0
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting()
            .UseMiddleware <BewitEndpointMiddleware>()
            .UseEndpoints(endpoints =>
            {
                endpoints.MapGet("/download/{id:int}", async c =>
                {
                    var bytes = Encoding.UTF8.GetBytes("hello world");
                    await c.Response.Body.WriteAsync(bytes, 0, bytes.Length);
                })
                .RequireBewitUrlAuthorization();

                endpoints.MapGet("/opensesame/{id:int}", async c =>
                {
                    var generator =
                        c.RequestServices.GetService <IBewitTokenGenerator <string> >();

                    var id = c.Request.RouteValues.GetValueOrDefault("id");

                    BewitToken <string> token =
                        await generator.GenerateBewitTokenAsync($"/download/{id}", default);

                    string html = @$ "<html><a href=" "/download/{id}?bewit={token}" ">download</a>
                                        <br>{(string)token}</html>";

                    var bytes = Encoding.UTF8.GetBytes(html);
                    await c.Response.Body.WriteAsync(bytes, 0, bytes.Length);
                });
            });
Esempio n. 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"));
            }
        }
Esempio n. 4
0
        private Bewit <T> DeserializeBewitWithoutValidation(BewitToken <T> bewit)
        {
            var base64Bewit     = bewit.ToString();
            var serializedBewit = Encoding.UTF8.GetString(Convert.FromBase64String(base64Bewit));

            // Refactor: TypeNameHandling.All
            return(JsonConvert.DeserializeObject <Bewit <T> >(serializedBewit));
        }
Esempio n. 5
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);
        }
Esempio n. 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"));
            }
        }
Esempio n. 7
0
        public async Task InvokeAsync(
            IMiddlewareContext context,
            IBewitTokenGenerator <TPayload> tokenGenerator)
        {
            await _next(context).ConfigureAwait(false);

            if (context.Result is TPayload result)
            {
                BewitToken <TPayload> bewit
                    = await tokenGenerator.GenerateBewitTokenAsync(
                          result,
                          context.RequestAborted);

                context.Result = (string)bewit;
            }
        }
Esempio n. 8
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);
        }
Esempio n. 9
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");
        }
Esempio n. 10
0
        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}");
        }
Esempio n. 11
0
        public async Task InvokeAsync(
            IMiddlewareContext context,
            IBewitTokenGenerator <string> tokenGenerator)
        {
            await _next(context).ConfigureAwait(false);

            if (context.Result is string result)
            {
                var uri = new Uri(result);

                BewitToken <string> bewit =
                    await tokenGenerator.GenerateBewitTokenAsync(
                        uri.PathAndQuery, context.RequestAborted);

                var parametersToAdd = new Dictionary <string, string>
                {
                    { "bewit", WebUtility.UrlEncode((string)bewit) }
                };
                var newUri =
                    QueryHelpers.AddQueryString(result, parametersToAdd);

                context.Result = newUri;
            }
        }