Skip to content

Commit

Permalink
Update auth implementation to match .NET 8 (#165)
Browse files Browse the repository at this point in the history
* Update security stub implementation

* Move to .NET 8 only
  • Loading branch information
Hawxy authored Jul 24, 2024
1 parent f360e65 commit d0c313b
Show file tree
Hide file tree
Showing 18 changed files with 62 additions and 76 deletions.
12 changes: 6 additions & 6 deletions src/Alba.Testing/Alba.Testing.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net6.0;net8.0</TargetFrameworks>
<DebugType>portable</DebugType>
<TargetFramework>net8.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Alba\Alba.csproj" />
Expand All @@ -14,11 +14,11 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
<PackageReference Include="NSubstitute" Version="5.1.0" />
<PackageReference Include="Shouldly" Version="4.2.1" />
<PackageReference Include="xunit" Version="2.6.6" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.6">
<PackageReference Include="xunit" Version="2.9.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Expand Down
2 changes: 1 addition & 1 deletion src/Alba.Testing/Samples/ContractTestWithAlba.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public async Task with_validation_errors()
{
_.Get.Url("/fake/invalid");
_.ContentTypeShouldBe("application/problem+json; charset=utf-8");
_.StatusCodeShouldBe(400);
_.StatusCodeShouldBe(500);
});

var problems = result.ReadAsJson<ProblemDetails>();
Expand Down
24 changes: 12 additions & 12 deletions src/Alba.Testing/Security/JwtSecurityStubTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,44 +39,44 @@ public JwtSecurityStubTests()
public void token_has_identifier()
{
theStub.BuildToken()
.Claims.ShouldContain(x => x.Type == JwtRegisteredClaimNames.Jti);
.Subject.Claims.ShouldContain(x => x.Type == JwtRegisteredClaimNames.Jti);
}

[Fact]
public void should_have_audience()
{
var token = theStub.BuildToken();
token
.Claims.FirstOrDefault(x => x.Type == JwtRegisteredClaimNames.Aud)
.Value.ShouldBe("chiefsfans");
token.Audience.ShouldBe("chiefsfans");
}

[Fact]
public void should_have_issuer_if_it_exists()
{
theStub.BuildToken()
.Claims.FirstOrDefault(x => x.Type == JwtRegisteredClaimNames.Iss)
theStub.BuildToken().Subject.Claims.First(x => x.Type == JwtRegisteredClaimNames.Iss)
.Value.ShouldBe("myapp");
}

[Fact]
public void has_all_the_baseline_claims()
{
var token = theStub.BuildToken();

token.Claims.Single(x => x.Type == "foo")

token
.Subject.Claims.Single(x => x.Type == "foo")
.Value.ShouldBe("bar");

token.Claims.Single(x => x.Type == "team")

token
.Subject.Claims.Single(x => x.Type == "team")
.Value.ShouldBe("chiefs");
}

[Fact]
public void additive_claims_on_the_token()
{
var token = theStub.BuildToken(new []{new Claim("division", "afcwest")});

token.Claims.Single(x => x.Type == "division")

token
.Subject.Claims.Single(x => x.Type == "division")
.Value.ShouldBe("afcwest");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public async Task post_to_a_secured_endpoint_with_jwt_from_extension()
x.StatusCodeShouldBeOk();
});

var output = response.ReadAsJson<Result>();
var output = await response.ReadAsJsonAsync<Result>();
output.Sum.ShouldBe(9);
output.Product.ShouldBe(24);
}
Expand Down
19 changes: 4 additions & 15 deletions src/Alba/Alba.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@
<PropertyGroup>
<Description>Supercharged integration testing for ASP.NET Core HTTP endpoints</Description>
<Version>8.0.0</Version>
<TargetFrameworks>net6.0;net7.0;net8.0</TargetFrameworks>
<TargetFramework>net8.0</TargetFramework>
<PackageProjectUrl>http://jasperfx.github.io/alba/</PackageProjectUrl>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>git://github.com/JasperFx/alba</RepositoryUrl>
<OutputType>library</OutputType>
<PackageIconUrl>https://avatars2.githubusercontent.com/u/10048186?v=3&amp;s=200</PackageIconUrl>
<langversion>10</langversion>
<nullable>enable</nullable>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>CS1591;</NoWarn>
Expand All @@ -19,22 +18,12 @@
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="IdentityModel" Version="6.2.0" />
<PackageReference Include="DotNet.ReproducibleBuilds" Version="1.1.1" PrivateAssets="All" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net6.0'">
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="6.0.10" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.28" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net7.0'">
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="7.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.17" />
<PackageReference Include="DotNet.ReproducibleBuilds" Version="1.2.4" PrivateAssets="All" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.3" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.7" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.7" />
</ItemGroup>

</Project>
19 changes: 13 additions & 6 deletions src/Alba/Security/JwtSecurityStub.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
Expand All @@ -10,6 +9,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.JsonWebTokens;
using Microsoft.IdentityModel.Protocols;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.IdentityModel.Tokens;
Expand Down Expand Up @@ -61,7 +61,7 @@ IHostBuilder IAlbaExtension.Configure(IHostBuilder builder)
});
}

internal JwtSecurityToken BuildToken(Claim[]? additionalClaims = null, string[]? removedClaims = null)
internal SecurityTokenDescriptor BuildToken(Claim[]? additionalClaims = null, string[]? removedClaims = null)
{
if (_options == null)
throw new InvalidOperationException("Unable to determine the JwtBearerOptions for this AlbaHost");
Expand All @@ -77,14 +77,21 @@ internal JwtSecurityToken BuildToken(Claim[]? additionalClaims = null, string[]?
_options.TokenValidationParameters.IssuerSigningKey,
algorithm);

return new JwtSecurityToken(_options.ClaimsIssuer, audience, processedClaims(additionalClaims, removedClaims),
expires: DateTime.UtcNow.AddDays(1), signingCredentials: credentials);
return new SecurityTokenDescriptor()
{
Subject = new ClaimsIdentity(processedClaims(additionalClaims, removedClaims)),
Issuer = _options.ClaimsIssuer,
Audience = audience,
Expires = DateTime.UtcNow.AddDays(1),
SigningCredentials = credentials
};
}

internal string BuildJwtString(Claim[] additionalClaims, string[]? removedClaims = null)
{
var token = BuildToken(additionalClaims, removedClaims);
return new JwtSecurityTokenHandler().WriteToken(token);
var tokenHandler = new JsonWebTokenHandler();
var tokenDescriptor = BuildToken(additionalClaims, removedClaims);
return tokenHandler.CreateToken(tokenDescriptor);
}

protected override IEnumerable<Claim> stubTypeSpecificClaims()
Expand Down
2 changes: 1 addition & 1 deletion src/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<PropertyGroup>
<WarningsAsErrors>NU1901;NU1902;NU1903;NU1904</WarningsAsErrors>
<WarningsAsErrors>NU1901;NU1902;NU1904</WarningsAsErrors>
<NuGetAuditMode>all</NuGetAuditMode>
<NuGetAuditLevel>low</NuGetAuditLevel>
</PropertyGroup>
Expand Down
8 changes: 3 additions & 5 deletions src/IdentityServer.New/IdentityServer.New.csproj
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Duende.IdentityServer" Version="6.3.8" />
<PackageReference Include="Duende.IdentityServer" Version="7.0.5" />
<PackageReference Include="IdentityModel" Version="6.2.0" />
<!-- explicit reference to avoid CVE -->
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.35.0" />
<PackageReference Include="Serilog.AspNetCore" Version="6.0.0" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"Version":1,"Id":"BAF757129D4DA200C5FD1BF53156790E","Created":"2024-07-24T11:43:55.5580267Z","Algorithm":"RS256","IsX509Certificate":false,"Data":"CfDJ8AjiBY8lL4pOrrMS71-cAqmVF6QemWkgsWqkQAIok3liy6J9PfVwWxEIomXKxStcXE88fpWoYhfB3-h4-kvyR1H-Oek6or63nKXWOdVZb2gaEGUlkfIrJLYkksVCa_Wg21MqCrK9d4aagyCyCur-UnoGREKEq1QRBf7OZ-uQyrAP3bzj4-S8AUWMCmgw848ObGW2TRcUUJuBVABCKkGjYb-NAWS8_LXVsXcCgqkGe-VcKZzUYsJSCShA8eQ4cy1AXPkjkQX12pQDpahLW0I4i9o5uRqzhXdeGj3Jl1yUZQGVUfoXRj-oJzsI0OZfDvdMcaM10C19pFtUtNdIsHG3LnaexwD3006fSC9InPJjWqfI1C7JypPAsQ0aXumSlk40yXqe6XrGyb3eBiWrIxwW-SkP1fZIV505zecvQepMZIstjxulBCjpjXC4XMalv6i1J2T67DTOAKOAe1OwckKgVV9I4-bVshlT3zNj6aBTEoDydhLSelFnanJALw5MN_qtVfDvt1902TDVaaK3wrI9e9kWDMGSh1ctgFy3bP28MgJlZ1_BJj2i1_5yCvZ93txKhz55whUA7OuPZRH1SmtcOjzUGqKXhkRGElVCFP6djFKMcO1G7WhpyrFa8ge8NE-eJp_qpAdMK0TNp0a4D9hwGfr3xMsQ0sfMt26twbWNjwqmB0qBaxRoKy493FC93GxfNaxrG_1eqJDyBKkmOyLbILnhzUYuYlEf3Ea3_o4pewqLQaShiQaRbkQY8ZDHUAQ4Mu3Y6GKetSHzB2UTy7NWcSnpuV06w_5OhnGhWjnXiNF4LCnaEXiyvx3xdmrhMq0f69WK-FEhOBN4oRRdH4Z1p8OcELMeIRsGkNcptDAPe1XBCvSBr8g4FxLO-ybxwmYlftmNQnA4pAFUDyCQd5l3VllKGhEerRdT4h3HXawnIxEr9R6wrsGDaWeRbFc7Mh0mH9XWulOFarv-TwoELuKMUfq8IaNwsgYgkJpR0kzRo6CykVIgXy6tKHz6ELK4harXtN4dGuNvtEtrmN19AXJzoESEbuCCLsT3nbwgE8kDaFrwdbgWhs0jjrDPjJfXyO4JSaLv1xikIzFRIOhHqXds8viu9vtshQ58ENeUerCF_ODugkzKM7vV7X0WPKlidZ4K6umv-Qh6jQ177ozvlPZBy2zOActfQmOqjXMxTzCBATajF1cupo_Upkfw2CMCsaA-FH1Ostxl27Ot_ZOvv2oP_YeA0leW1-AbqEVDbaIpjN6ri1fJDXPfZEMBj1UT8Q5u-qIdhFHh08iGK3Fh_PSFkrT8pSn3lin8xeEcWK40J9jgar-pFeCrq5ZYGc-xYHnodhnMKJ8WiSyrcJ0cDEPDgtKXDEKx-OUlGcJXhHDTTgopBARZHQxRNvuDFxfgk9fZJRLbQWg4H3CXLgO4kXjv5bzqy-NWwazIV0ZM-Hd1F3V8JQXB-EfO5JvPldZcOm2bNOtQ-jlqDgtC_1zRUV6NnBG3N3DcJz6_z9kliLD4U85yJCr8fYTcgC9EK65-ZVFxbL81J17e6AKYmsQfD7NAG9SoA9IycJ3Yz3vXTHVdsCl-2TrkhSfwaHN1bNMI3chWDHc2Q9A0j73_3SQ71h-BSQTiSFO-7dNEoqzN_6qhHE3TvEdSfCBkgp1GXotQo6Ms8X9vNvxpfH0uU67P3cxUxjtDYTv-Q9YjUclNZ9Qk2_ZOXkOkuCRQSg9t93tn7Ird9g3EnZ5yuqL6H_u19nNKmqDSqwVefeElyZL7WxnRrdgdsVvXP-OjCtzPUoQQAP9xiI3LnFXddzhEyJyiNEwjTxy1J2VAJCYnD6WDiVxbuYildyb5h5GjNHgTpLDL7TKPW6eg40psasSIsHQ52oiTnnQlLnRPTiXw4UYz1jISprKo0FOgNapKisnROuS_MJR7j2pr0asw7ZO5LHHqHj5hs_ITGM7rthIbEOZi16L37i6jNvTNU7JpTen-DPDmw066ZdZP60v3VZN0TghEWOPsBCGCCWHzC_wUUCUxprwLSkbhgcR-3W5Klc2TYWjnfCD0BtQ4kGu4FeDsgOaRMh7yAF2Q5dYa0fUg3rUBSq-0iEOfB1xvdd4gAiNfnlbZxekFxCH4De9dK572yOnBq9q06etTpxYEkPN_7pXSkPuVoXKpjpWTXPxwlyqIx8isBrdM__cAO6uRZxOXIXuv9nBE5pZ6aU1LysNtiSmYdLsHg9atAz8QYIJG1GON4BgeXI4vZTwdtsSeyAg3HozM0LwkJgjfA7uJtHrBP1GUWhimNftAV9V0_got5HlJhMHcY0ZveOk-l7dJGdYcP9Pah5L1YabbsaBjHKqt5w8TMw8YuprcWxTvWPSQeAX9jSy8pOeFdMrhTf7nhKxm5Wy09YuC20hRjxkMnVuveYUH8fsIDqW2ECbbiG2pH-mAoa_uNZz1bHRajJxwyLkUh7pO3bbg3p44UvGKSG95N1b3jR4NwxHq","DataProtected":true}
2 changes: 1 addition & 1 deletion src/MinimalApiWithOakton/MinimalApiWithOakton.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Lamar.Microsoft.DependencyInjection" Version="13.0.2" />
<PackageReference Include="Lamar.Microsoft.DependencyInjection" Version="13.0.4" />
<PackageReference Include="Oakton" Version="6.1.0" />
</ItemGroup>

Expand Down
4 changes: 2 additions & 2 deletions src/NUnitSamples/NUnitSamples.csproj
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
<TargetFramework>net8.0</TargetFramework>

<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="NUnit" Version="4.0.1" />
<PackageReference Include="NUnit" Version="4.1.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
</ItemGroup>

Expand Down
2 changes: 1 addition & 1 deletion src/WebApiAspNetCore3/WebApiStartupHostingModel.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>

</Project>
2 changes: 1 addition & 1 deletion src/WebApiNet6/WebApiNet6.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
Expand Down
13 changes: 4 additions & 9 deletions src/WebApp/Controllers/FakeController.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using System;
using Hellang.Middleware.ProblemDetails;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace WebApp.Controllers
Expand All @@ -9,24 +9,19 @@ namespace WebApp.Controllers
public class FakeController : ControllerBase
{
[HttpGet("{status}")]
public string Fake(string status)
public IResult Fake(string status)
{
switch (status)
{
case "bad":
throw new DivideByZeroException("Boom!");

case "invalid":
throw new ProblemDetailsException(new ProblemDetails
{
Status = 400,
Detail = "It's all wrong",
Title = "This stinks!"
});
return Results.Problem("It's all wrong", title: "This stinks!");

default:

return "it's all good";
return Results.Ok("it's all good");
}
}
}
Expand Down
7 changes: 3 additions & 4 deletions src/WebApp/Startup.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Hellang.Middleware.ProblemDetails;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
Expand Down Expand Up @@ -35,8 +34,8 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
FileProvider = new PhysicalFileProvider(env.ContentRootPath)
});

app.UseProblemDetails();

app.UseExceptionHandler();
app.UseRouting();

app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
Expand Down
7 changes: 3 additions & 4 deletions src/WebApp/WebApp.csproj
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<PreserveCompilationContext>true</PreserveCompilationContext>
<AssemblyName>WebApp</AssemblyName>
<OutputType>Exe</OutputType>
<PackageId>WebApp</PackageId>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Hellang.Middleware.ProblemDetails" Version="6.5.1" />
<PackageReference Include="JasperFx.Core" Version="1.5.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.10" />
<PackageReference Include="JasperFx.Core" Version="1.8.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.7" />
</ItemGroup>

</Project>
5 changes: 2 additions & 3 deletions src/WebAppSecuredWithJwt/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,16 @@ public void ConfigureServices(IServiceCollection services)
// don't worry about this, our JwtSecurityStub is gonna switch it off in
// tests
options.Authority = "https://localhost:5010";
options.Authority = "https://localhost:5001";
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateAudience = false,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("some really big key that should work")),
NameClaimType = ClaimTypes.NameIdentifier
};
});

}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
Expand Down
7 changes: 3 additions & 4 deletions src/WebAppSecuredWithJwt/WebAppSecuredWithJwt.csproj
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.28" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.35.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.7" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
</ItemGroup>

</Project>

0 comments on commit d0c313b

Please sign in to comment.