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