Example #1
0
        public async Task calls_to_local_endpoint_without_antiforgery_should_not_require_csrf()
        {
            var req      = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/local_anon_no_csrf"));
            var response = await BffHost.BrowserClient.SendAsync(req);

            response.StatusCode.Should().Be(HttpStatusCode.OK);
        }
Example #2
0
        public async Task logout_endpoint_for_anonymous_user_without_sid_should_succeed()
        {
            var response = await BffHost.BrowserClient.GetAsync(BffHost.Url("/bff/logout"));

            response.StatusCode.Should().Be(302); // endsession
            response.Headers.Location.ToString().ToLowerInvariant().Should().StartWith(IdentityServerHost.Url("/connect/endsession"));
        }
Example #3
0
        public async Task calls_to_remote_endpoint_should_require_csrf()
        {
            var req      = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/api_user_or_client/test"));
            var response = await BffHost.BrowserClient.SendAsync(req);

            response.StatusCode.Should().Be(HttpStatusCode.Unauthorized);
        }
Example #4
0
        public async Task custom_header_should_be_forwarded_and_xforwarded_headers_should_be_created()
        {
            BffHost.BffOptions.AddXForwardedHeaders = true;
            BffHost.BffOptions.ForwardedHeaders.Add("x-custom");

            await BffHost.InitializeAsync();

            var req = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/api_anon_only/test"));

            req.Headers.Add("x-csrf", "1");
            req.Headers.Add("x-custom", "custom");
            var response = await BffHost.BrowserClient.SendAsync(req);

            response.IsSuccessStatusCode.Should().BeTrue();
            var json = await response.Content.ReadAsStringAsync();

            var apiResult = JsonSerializer.Deserialize <ApiResponse>(json);

            apiResult.RequestHeaders.Count.Should().Be(4);

            apiResult.RequestHeaders["X-Forwarded-Host"].Single().Should().Be("app");
            apiResult.RequestHeaders["X-Forwarded-Proto"].Single().Should().Be("https");
            apiResult.RequestHeaders["Host"].Single().Should().Be("api");
            apiResult.RequestHeaders["x-custom"].Single().Should().Be("custom");
        }
Example #5
0
        public void calls_to_endpoint_without_bff_metadata_should_fail()
        {
            var req = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/not_bff_endpoint"));

            Func <Task> f = () => BffHost.BrowserClient.SendAsync(req);

            f.Should().Throw <Exception>();
        }
Example #6
0
        public async Task logout_endpoint_should_reject_non_local_returnUrl()
        {
            await BffHost.BffLoginAsync("alice", "sid123");

            Func <Task> f = () => BffHost.BrowserClient.GetAsync(BffHost.Url("/bff/logout") + "?sid=sid123&returnUrl=https://foo");

            f.Should().Throw <Exception>().And.Message.Should().Contain("returnUrl");
        }
Example #7
0
        public void calls_to_bff_not_in_endpoint_routing_should_fail()
        {
            var req = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/invalid_endpoint/test"));

            Func <Task> f = () => BffHost.BrowserClient.SendAsync(req);

            f.Should().Throw <Exception>();
        }
Example #8
0
        public async Task user_endpoint_for_authenticated_user_without_csrf_header_should_fail()
        {
            await BffHost.IssueSessionCookieAsync(new Claim("sub", "alice"), new Claim("foo", "foo1"), new Claim("foo", "foo2"));

            var req      = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/bff/user"));
            var response = await BffHost.BrowserClient.SendAsync(req);

            response.StatusCode.Should().Be(401);
        }
Example #9
0
        public async Task unauthenticated_calls_to_authorized_local_endpoint_should_fail()
        {
            var req = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/local_authz"));

            req.Headers.Add("x-csrf", "1");
            var response = await BffHost.BrowserClient.SendAsync(req);

            response.StatusCode.Should().Be(HttpStatusCode.Unauthorized);
        }
Example #10
0
        public async Task user_endpoint_for_unauthenticated_user_should_fail()
        {
            var req = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/bff/user"));

            req.Headers.Add("x-csrf", "1");
            var response = await BffHost.BrowserClient.SendAsync(req);

            response.StatusCode.Should().Be(401);
        }
Example #11
0
        public async Task unauthenticated_api_call_should_return_401()
        {
            var req = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/always_fail_authz"));

            req.Headers.Add("x-csrf", "1");
            var response = await BffHost.BrowserClient.SendAsync(req);

            response.StatusCode.Should().Be(HttpStatusCode.Unauthorized);
        }
Example #12
0
        public async Task login_endpoint_with_existing_session_should_challenge()
        {
            await BffHost.BffLoginAsync("alice");

            var response = await BffHost.BrowserClient.GetAsync(BffHost.Url("/bff/login"));

            response.StatusCode.Should().Be(HttpStatusCode.Redirect);
            response.Headers.Location.ToString().Should().StartWith(IdentityServerHost.Url("/connect/authorize"));
        }
Example #13
0
        public async Task calls_to_local_endpoint_should_require_csrf()
        {
            await BffHost.BffLoginAsync("alice");

            var req      = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/local_anon"));
            var response = await BffHost.BrowserClient.SendAsync(req);

            response.StatusCode.Should().Be(HttpStatusCode.Unauthorized);
        }
Example #14
0
        public async Task unauthenticated_non_bff_endpoint_should_return_302_for_login()
        {
            var req = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/always_fail_authz_non_bff_endpoint"));

            req.Headers.Add("x-csrf", "1");
            var response = await BffHost.BrowserClient.SendAsync(req);

            response.StatusCode.Should().Be(HttpStatusCode.Redirect);
            response.Headers.Location.ToString().ToLowerInvariant().Should().StartWith(IdentityServerHost.Url("/connect/authorize"));
        }
Example #15
0
        public async Task logout_endpoint_for_authenticated_when_require_otpion_is_false_should_not_require_sid()
        {
            await BffHost.BffLoginAsync("alice", "sid123");

            BffHost.BffOptions.RequireLogoutSessionId = false;

            var response = await BffHost.BrowserClient.GetAsync(BffHost.Url("/bff/logout"));

            response.StatusCode.Should().Be(302); // endsession
            response.Headers.Location.ToString().ToLowerInvariant().Should().StartWith(IdentityServerHost.Url("/connect/endsession"));
        }
Example #16
0
        public async Task forbidden_api_call_should_return_403()
        {
            await BffHost.BffLoginAsync("alice");

            var req = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/always_fail_authz"));

            req.Headers.Add("x-csrf", "1");
            var response = await BffHost.BrowserClient.SendAsync(req);

            response.StatusCode.Should().Be(HttpStatusCode.Forbidden);
        }
Example #17
0
        public async Task calls_to_remote_endpoint_with_useraccesstokenparameters_having_not_stored_corresponding_named_token_finds_no_matching_token_should_fail()
        {
            var loginResponse = await BffHostWithNamedTokens.BffLoginAsync("alice");

            var req = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/api_user_with_useraccesstokenparameters_having_not_stored_named_token/test"));

            req.Headers.Add("x-csrf", "1");

            Func <Task> f = () => BffHostWithNamedTokens.BrowserClient.SendAsync(req);

            f.Should().Throw <Exception>();
        }
Example #18
0
        public async Task logout_endpoint_for_authenticated_user_without_sid_should_succeed()
        {
            // workaround for RevokeUserRefreshTokenAsync throwing when no RT in session
            BffHost.BffOptions.RevokeRefreshTokenOnLogout = false;
            await BffHost.InitializeAsync();

            await BffHost.IssueSessionCookieAsync("alice");

            var response = await BffHost.BrowserClient.GetAsync(BffHost.Url("/bff/logout"));

            response.StatusCode.Should().Be(302); // endsession
            response.Headers.Location.ToString().ToLowerInvariant().Should().StartWith(IdentityServerHost.Url("/connect/endsession"));
        }
Example #19
0
        public async Task response_status_403_from_remote_endpoint_should_return_403_from_bff()
        {
            await BffHost.BffLoginAsync("alice");

            ApiHost.ApiStatusCodeToReturn = 403;

            var req = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/api_user/test"));

            req.Headers.Add("x-csrf", "1");
            var response = await BffHost.BrowserClient.SendAsync(req);

            response.StatusCode.Should().Be(HttpStatusCode.Forbidden);
        }
Example #20
0
        public async Task response_status_403_should_return_403()
        {
            await BffHost.BffLoginAsync("alice");

            BffHost.LocalApiStatusCodeToReturn = 403;

            var req = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/local_authz"));

            req.Headers.Add("x-csrf", "1");
            var response = await BffHost.BrowserClient.SendAsync(req);

            response.StatusCode.Should().Be(HttpStatusCode.Forbidden);
        }
Example #21
0
        public async Task local_endpoint_should_receive_standard_headers()
        {
            var req = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/local_anon"));
            req.Headers.Add("x-csrf", "1");
            var response = await BffHost.BrowserClient.SendAsync(req);

            response.IsSuccessStatusCode.Should().BeTrue();
            var json = await response.Content.ReadAsStringAsync();
            var apiResult = JsonSerializer.Deserialize<ApiResponse>(json);

            apiResult.RequestHeaders.Count.Should().Be(2);
            apiResult.RequestHeaders["Host"].Single().Should().Be("app");
            apiResult.RequestHeaders["x-csrf"].Single().Should().Be("1");
        }
Example #22
0
        public async Task bff_host_name_should_propagate_to_api()
        {
            var req = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/api_anon_only/test"));

            req.Headers.Add("x-csrf", "1");
            var response = await BffHost.BrowserClient.SendAsync(req);

            response.IsSuccessStatusCode.Should().BeTrue();
            var json = await response.Content.ReadAsStringAsync();

            var apiResult = JsonSerializer.Deserialize <ApiResponse>(json);

            var host = apiResult.RequestHeaders["Host"].Single();

            host.Should().Be("app");
        }
Example #23
0
        public async Task calls_to_anon_endpoint_should_allow_anonymous()
        {
            var req = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/local_anon"));

            req.Headers.Add("x-csrf", "1");
            var response = await BffHost.BrowserClient.SendAsync(req);

            response.IsSuccessStatusCode.Should().BeTrue();
            response.Content.Headers.ContentType.MediaType.Should().Be("application/json");
            var json = await response.Content.ReadAsStringAsync();

            var apiResult = JsonSerializer.Deserialize <ApiResponse>(json);

            apiResult.Method.Should().Be("GET");
            apiResult.Path.Should().Be("/local_anon");
            apiResult.Sub.Should().BeNull();
        }
Example #24
0
        public async Task calls_to_authorized_local_endpoint_without_csrf_should_succeed()
        {
            await BffHost.BffLoginAsync("alice");

            var req      = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/local_authz_no_csrf"));
            var response = await BffHost.BrowserClient.SendAsync(req);

            response.IsSuccessStatusCode.Should().BeTrue();
            response.Content.Headers.ContentType.MediaType.Should().Be("application/json");
            var json = await response.Content.ReadAsStringAsync();

            var apiResult = JsonSerializer.Deserialize <ApiResponse>(json);

            apiResult.Method.Should().Be("GET");
            apiResult.Path.Should().Be("/local_authz_no_csrf");
            apiResult.Sub.Should().Be("alice");
        }
Example #25
0
        public async Task endpoints_that_disable_csrf_should_not_require_csrf_header()
        {
            await BffHost.BffLoginAsync("alice");

            var req      = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/api_user_no_csrf/test"));
            var response = await BffHost.BrowserClient.SendAsync(req);

            response.IsSuccessStatusCode.Should().BeTrue();
            response.Content.Headers.ContentType.MediaType.Should().Be("application/json");
            var json = await response.Content.ReadAsStringAsync();

            var apiResult = JsonSerializer.Deserialize <ApiResponse>(json);

            apiResult.Method.Should().Be("GET");
            apiResult.Path.Should().Be("/test");
            apiResult.Sub.Should().Be("alice");
            apiResult.ClientId.Should().Be("spa");
        }
Example #26
0
        public async Task login_endpoint_should_challenge_and_redirect_to_root()
        {
            var response = await BffHost.BrowserClient.GetAsync(BffHost.Url("/bff/login"));

            response.StatusCode.Should().Be(HttpStatusCode.Redirect);
            response.Headers.Location.ToString().Should().StartWith(IdentityServerHost.Url("/connect/authorize"));

            await IdentityServerHost.IssueSessionCookieAsync("alice");

            response = await IdentityServerHost.BrowserClient.GetAsync(response.Headers.Location.ToString());

            response.StatusCode.Should().Be(HttpStatusCode.Redirect);
            response.Headers.Location.ToString().Should().StartWith(BffHost.Url("/signin-oidc"));

            response = await BffHost.BrowserClient.GetAsync(response.Headers.Location.ToString());

            response.StatusCode.Should().Be(HttpStatusCode.Redirect);
            response.Headers.Location.ToString().Should().Be("/");
        }
Example #27
0
        public async Task forwarded_host_name_should_propagate_to_api()
        {
            BffHost.BffOptions.ForwardIncomingXForwardedHeaders = true;
            await BffHost.InitializeAsync();

            var req = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/api_anon_only/test"));

            req.Headers.Add("x-csrf", "1");
            req.Headers.Add("X-Forwarded-Host", "external");
            var response = await BffHost.BrowserClient.SendAsync(req);

            response.IsSuccessStatusCode.Should().BeTrue();
            var json = await response.Content.ReadAsStringAsync();

            var apiResult = JsonSerializer.Deserialize <ApiResponse>(json);

            var host = apiResult.RequestHeaders["Host"].Single();

            host.Should().Be("external");
        }
Example #28
0
        public async Task calls_to_remote_endpoint_should_forward_user_to_api()
        {
            await BffHost.BffLoginAsync("alice");

            var req = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/api_user/test"));

            req.Headers.Add("x-csrf", "1");
            var response = await BffHost.BrowserClient.SendAsync(req);

            response.IsSuccessStatusCode.Should().BeTrue();
            response.Content.Headers.ContentType.MediaType.Should().Be("application/json");
            var json = await response.Content.ReadAsStringAsync();

            var apiResult = JsonSerializer.Deserialize <ApiResponse>(json);

            apiResult.Method.Should().Be("GET");
            apiResult.Path.Should().Be("/test");
            apiResult.Sub.Should().Be("alice");
            apiResult.ClientId.Should().Be("spa");
        }
Example #29
0
        public async Task login_endpoint_should_challenge_and_redirect_to_root_with_custom_prefix_trailing_slash()
        {
            BffHost.BffOptions.ManagementBasePath = "/custom/bff/";
            await BffHost.InitializeAsync();

            var response = await BffHost.BrowserClient.GetAsync(BffHost.Url("/custom/bff/login"));

            response.StatusCode.Should().Be(HttpStatusCode.Redirect);
            response.Headers.Location.ToString().Should().StartWith(IdentityServerHost.Url("/connect/authorize"));

            await IdentityServerHost.IssueSessionCookieAsync("alice");

            response = await IdentityServerHost.BrowserClient.GetAsync(response.Headers.Location.ToString());

            response.StatusCode.Should().Be(HttpStatusCode.Redirect);
            response.Headers.Location.ToString().Should().StartWith(BffHost.Url("/signin-oidc"));

            response = await BffHost.BrowserClient.GetAsync(response.Headers.Location.ToString());

            response.StatusCode.Should().Be(HttpStatusCode.Redirect);
            response.Headers.Location.ToString().Should().Be("/");
        }
Example #30
0
        public async Task calls_to_remote_endpoint_expecting_token_but_without_token_should_fail()
        {
            var client = IdentityServerHost.Clients.Single(x => x.ClientId == "spa");

            client.Enabled = false;

            {
                var req = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/api_user_or_client/test"));
                req.Headers.Add("x-csrf", "1");
                var response = await BffHost.BrowserClient.SendAsync(req);

                response.StatusCode.Should().Be(HttpStatusCode.Unauthorized);
            }

            {
                var req = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/api_client/test"));
                req.Headers.Add("x-csrf", "1");
                var response = await BffHost.BrowserClient.SendAsync(req);

                response.StatusCode.Should().Be(HttpStatusCode.Unauthorized);
            }
        }