|
2 | 2 | // See LICENSE in the project root for license information. |
3 | 3 |
|
4 | 4 | using System.Net; |
| 5 | +using Duende.Bff.DynamicFrontends; |
5 | 6 | using Duende.Bff.Tests.TestFramework; |
6 | 7 | using Duende.Bff.Tests.TestInfra; |
7 | 8 | using Microsoft.AspNetCore.Authentication; |
@@ -311,4 +312,59 @@ public async Task fallback_policy_should_not_fail(BffSetupType setup) |
311 | 312 | var response = await Bff.BrowserClient.GetAsync(Bff.Url("/not-found")); |
312 | 313 | response.StatusCode.ShouldBe(HttpStatusCode.NotFound); |
313 | 314 | } |
| 315 | + |
| 316 | + [Fact] |
| 317 | + |
| 318 | + public async Task authorization_policy_failure_should_return_403() |
| 319 | + { |
| 320 | + var identityServer = new IdentityServerTestHost(Context); |
| 321 | + var bff = new BffTestHost(Context, identityServer); |
| 322 | + identityServer.AddClient(The.ClientId, bff.Url()); |
| 323 | + |
| 324 | + bff.OnConfigureBffOptions += opt => |
| 325 | + { |
| 326 | + opt.BackchannelHttpHandler = Internet; |
| 327 | + opt.ConfigureOpenIdConnectDefaults = The.DefaultOpenIdConnectConfiguration; |
| 328 | + }; |
| 329 | + |
| 330 | + // this is regards to an issue reported by one of our users: |
| 331 | + // https://github.com/orgs/DuendeSoftware/discussions/488 |
| 332 | + // We have to explicitly configure the authentication schemes, but |
| 333 | + // not set the DefaultForbidScheme, otherwise when an authorization policy |
| 334 | + // fails, the BFF doesn't know which scheme to use for the forbid response, |
| 335 | + // and that causes a StackOverflowException. |
| 336 | + bff.OnConfigureServices += s => s.AddAuthentication(options => |
| 337 | + { |
| 338 | + options.DefaultScheme = BffAuthenticationSchemes.BffCookie; |
| 339 | + options.DefaultChallengeScheme = BffAuthenticationSchemes.BffOpenIdConnect; |
| 340 | + options.DefaultSignOutScheme = BffAuthenticationSchemes.BffOpenIdConnect; |
| 341 | + }); |
| 342 | + |
| 343 | + // This test verifies that when an authorization policy fails (not just RequireAuthenticatedUser, |
| 344 | + // but a custom policy like RequireClaim), the BFF correctly returns 403 without causing |
| 345 | + // a StackOverflowException. This was a bug when DefaultForbidScheme was not set. |
| 346 | + AddCustomUserClaims(new System.Security.Claims.Claim("given_name", "Alice")); |
| 347 | + |
| 348 | + bff.OnConfigureApp += app => |
| 349 | + { |
| 350 | + app.Map(The.Path, c => ApiHost.ReturnApiCallDetails(c, () => LocalApiResponseStatus)) |
| 351 | + .RequireAuthorization(policy => |
| 352 | + { |
| 353 | + policy.RequireAuthenticatedUser(); |
| 354 | + policy.RequireClaim("given_name", "Bob"); // Alice won't have this claim |
| 355 | + }) |
| 356 | + .AsBffApiEndpoint(); |
| 357 | + }; |
| 358 | + |
| 359 | + await identityServer.InitializeAsync(); |
| 360 | + await bff.InitializeAsync(); |
| 361 | + |
| 362 | + await bff.BrowserClient.Login(); |
| 363 | + bff.BrowserClient.RedirectHandler.AutoFollowRedirects = false; |
| 364 | + |
| 365 | + await bff.BrowserClient.CallBffHostApi( |
| 366 | + url: Bff.Url(The.Path), |
| 367 | + expectedStatusCode: HttpStatusCode.Forbidden |
| 368 | + ); |
| 369 | + } |
314 | 370 | } |
0 commit comments