Skip to content

Commit

Permalink
Fix JWT stub compatibility with IdentityWeb (#183)
Browse files Browse the repository at this point in the history
* Fix JWT stub compatibility with IdentityWeb

* Version bump

---------

Co-authored-by: JT <Hawxy@users.noreply.github.com>
  • Loading branch information
Hawxy and Hawxy authored Jan 11, 2025
1 parent 2b80fdd commit 7fa9072
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
using System.Net;
using System.Threading.Tasks;
using Alba.Security;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.JsonWebTokens;
using Microsoft.IdentityModel.Protocols;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Shouldly;
using Xunit;

namespace Alba.Testing.Security;
Expand Down Expand Up @@ -39,7 +45,7 @@ await host.Scenario(s =>
public async Task can_stub_individual_scheme_jwt()
{
// This is a Alba extension that can "stub" out authentication
var securityStub = new JwtSecurityStub("custom")
var securityStub = new JwtSecurityStub(JwtBearerDefaults.AuthenticationScheme)
.With("foo", "bar")
.With(JwtRegisteredClaimNames.Email, "guy@company.com")
.WithName("jeremy");
Expand All @@ -49,15 +55,61 @@ public async Task can_stub_individual_scheme_jwt()

await host.Scenario(s =>
{
s.Get.Url("/identity2");
s.Get.Url("/identity");
s.StatusCodeShouldBeOk();
});

await host.Scenario(s =>
{
s.Get.Url("/identity");
s.Get.Url("/identity2");
s.StatusCodeShouldBe(HttpStatusCode.Unauthorized);
});

}

[Fact]
public async Task can_stub_individual_schemes_microsoft_identity_web()
{
var securityStub1 = new AuthenticationStub("custom")
.With("foo", "bar")
.With(JwtRegisteredClaimNames.Email, "guy@company.com")
.WithName("jeremy");

var securityStub2 = new JwtSecurityStub(JwtBearerDefaults.AuthenticationScheme)
.With("foo", "bar")
.With(JwtRegisteredClaimNames.Email, "guy@company.com")
.WithName("jeremy");

var securityStub3 = new JwtSecurityStub("AzureAuthentication")
.With("iss", "bar")
.With("tid", "tenantid")
.With("roles", "")
.With(JwtRegisteredClaimNames.Email, "guy@company.com")
.WithName("jeremy");

// We're calling your real web service's configuration
await using var host = await AlbaHost.For<WebAppSecuredWithJwt.Program>(securityStub1, securityStub2, securityStub3);
var postConfigures = host.Services.GetRequiredService<IOptionsMonitor<JwtBearerOptions>>().Get("AzureAuthentication");

postConfigures.ConfigurationManager.ShouldBeOfType<StaticConfigurationManager<OpenIdConnectConfiguration>>();

await host.Scenario(s =>
{
s.Get.Url("/identity");
s.StatusCodeShouldBeOk();
});

await host.Scenario(s =>
{
s.Get.Url("/identity2");
s.StatusCodeShouldBeOk();
});

await host.Scenario(s =>
{
s.Get.Url("/identity3");
s.StatusCodeShouldBeOk();
});

}
}
2 changes: 1 addition & 1 deletion src/Alba/Alba.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<Description>Supercharged integration testing for ASP.NET Core HTTP endpoints</Description>
<Version>8.1.0</Version>
<Version>8.1.1</Version>
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
<PackageProjectUrl>http://jasperfx.github.io/alba/</PackageProjectUrl>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
Expand Down
3 changes: 2 additions & 1 deletion src/Alba/Security/JwtSecurityStub.cs
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,9 @@ void PostConfigure(JwtBearerOptions options)
});

var validationParameters = options.TokenValidationParameters.Clone();
validationParameters.IssuerSigningKey ??= new SymmetricSecurityKey(Encoding.UTF8.GetBytes("some really big key that should work"));
validationParameters.IssuerSigningKey ??= new SymmetricSecurityKey("some really big key that should work"u8.ToArray());
validationParameters.ValidateIssuer = false;
validationParameters.IssuerValidator = (issuer, token, parameters) => issuer;
options.TokenValidationParameters = validationParameters;

options.Authority = null;
Expand Down
11 changes: 11 additions & 0 deletions src/WebAppSecuredWithJwt/IdentityController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,15 @@ public IActionResult Get()
return new JsonResult(from c in User.Claims select new { c.Type, c.Value });
}
}

[Route("identity3")]
[Authorize(AuthenticationSchemes = "AzureAuthentication")]
public class Identity3Controller : ControllerBase
{
[HttpGet]
public IActionResult Get()
{
return new JsonResult(from c in User.Claims select new { c.Type, c.Value });
}
}
}
5 changes: 5 additions & 0 deletions src/WebAppSecuredWithJwt/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Identity.Web;
using Microsoft.IdentityModel.Logging;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;

Expand All @@ -37,6 +39,9 @@ public void ConfigureServices(IServiceCollection services)
c.SwaggerDoc("v1", new OpenApiInfo {Title = "WebAppSecuredWithJwt", Version = "v1"});
});

services.AddMicrosoftIdentityWebApiAuthentication(Configuration, "AzureAdB2C", "AzureAuthentication");
IdentityModelEventSource.LogCompleteSecurityArtifact = true;
IdentityModelEventSource.ShowPII = true;
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
Expand Down
1 change: 1 addition & 0 deletions src/WebAppSecuredWithJwt/WebAppSecuredWithJwt.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.7" />
<PackageReference Include="Microsoft.Identity.Web" Version="3.5.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="7.2.0" />
</ItemGroup>

Expand Down
9 changes: 9 additions & 0 deletions src/WebAppSecuredWithJwt/appsettings.Development.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,14 @@
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AzureAdB2C": {
"Instance": "https://dummy.b2clogin.com",
"Domain": "dummy.onmicrosoft.com",
"TenantId": "sometenantid",
"Audience": "someaudience",
"ClientId": "someclientid",
"SignedOutCallbackPath": "/signout-oidc",
"SignUpSignInPolicyId": "B2C_1A_SIGNUP_SIGNIN"
}
}

0 comments on commit 7fa9072

Please sign in to comment.