mirror of
https://github.com/DuendeSoftware/products
synced 2026-05-24 09:28:24 +00:00
Merge pull request #1998 from DuendeSoftware/ka-fix-WWWAuthenticate
Ensure WWW-Authenticate uses a single HTTP header
This commit is contained in:
commit
97927d9219
10 changed files with 90 additions and 9 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
# Visual Studio Code workspace options
|
||||
.vscode/settings.json
|
||||
|
|
@ -27,6 +27,7 @@
|
|||
<!--tests -->
|
||||
<PackageReference Update="FluentAssertions" Version="6.5.1"/>
|
||||
<PackageReference Update="FluentAssertions.Web" Version="1.5.0"/>
|
||||
<PackageReference Update="Shouldly" Version="4.2.1" />
|
||||
<PackageReference Update="Microsoft.NET.Test.Sdk" Version="17.8.0"/>
|
||||
<PackageReference Update="xunit" Version="2.9.0"/>
|
||||
<PackageReference Update="xunit.runner.visualstudio" Version="2.5.4" PrivateAssets="All"/>
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ using Microsoft.Extensions.Primitives;
|
|||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using Duende.IdentityModel;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Duende.IdentityServer.Endpoints.Results;
|
||||
|
||||
|
|
@ -59,16 +60,24 @@ internal class ProtectedResourceErrorHttpWriter : IHttpResponseWriter<ProtectedR
|
|||
errorDescription = "The access token expired";
|
||||
}
|
||||
|
||||
var errorString = string.Format($"error=\"{error}\"");
|
||||
if (errorDescription.IsMissing())
|
||||
var values = new List<string>
|
||||
{
|
||||
context.Response.Headers.Append(HeaderNames.WWWAuthenticate, new StringValues(new[] { "Bearer realm=\"IdentityServer\"", errorString }));
|
||||
}
|
||||
else
|
||||
"""
|
||||
Bearer realm="IdentityServer"
|
||||
""",
|
||||
$"""
|
||||
error="{error}"
|
||||
"""
|
||||
};
|
||||
|
||||
if (!errorDescription.IsMissing())
|
||||
{
|
||||
var errorDescriptionString = string.Format($"error_description=\"{errorDescription}\"");
|
||||
context.Response.Headers.Append(HeaderNames.WWWAuthenticate, new StringValues(new[] { "Bearer realm=\"IdentityServer\"", errorString, errorDescriptionString }));
|
||||
values.Add($"""
|
||||
error_description="{errorDescription}"
|
||||
""");
|
||||
}
|
||||
|
||||
context.Response.Headers.Append(HeaderNames.WWWAuthenticate, string.Join(",", values));
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="FluentAssertions" />
|
||||
<PackageReference Include="Shouldly" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.TestHost" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" />
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
<PackageReference Include="xunit" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" />
|
||||
<PackageReference Include="FluentAssertions" />
|
||||
<PackageReference Include="Shouldly" />
|
||||
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" />
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
<PackageReference Include="xunit" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" />
|
||||
<PackageReference Include="FluentAssertions" />
|
||||
<PackageReference Include="Shouldly" />
|
||||
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" />
|
||||
|
|
@ -21,7 +22,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<!-- The packages in this ItemGroup are all transitive dependencies that
|
||||
would otherwise resolve to a version with a security vulnerabilitiy.
|
||||
would otherwise resolve to a version with a security vulnerability.
|
||||
In future, we would like to update Microsoft.Data.SqlClient and
|
||||
Microsoft.EntityFrameworkCore, and remove these explicit dependencies
|
||||
(assuming that future versions of the intermediate dependencies that
|
||||
|
|
@ -36,4 +37,4 @@
|
|||
<ProjectReference Include="..\..\src\IdentityServer\Duende.IdentityServer.csproj" />
|
||||
<ProjectReference Include="..\..\src\Storage\Duende.IdentityServer.Storage.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentAssertions" />
|
||||
<PackageReference Include="Shouldly" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" />
|
||||
<PackageReference Include="xunit" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" />
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
<PackageReference Include="xunit.runner.visualstudio" PrivateAssets="All" />
|
||||
<PackageReference Include="FluentAssertions" />
|
||||
<PackageReference Include="FluentAssertions.Web" />
|
||||
<PackageReference Include="Shouldly" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,63 @@
|
|||
// Copyright (c) Duende Software. All rights reserved.
|
||||
// See LICENSE in the project root for license information.
|
||||
|
||||
using Duende.IdentityServer.Endpoints.Results;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
|
||||
namespace UnitTests.Endpoints.Results;
|
||||
|
||||
public class ProtectedResourceErrorResultTests
|
||||
{
|
||||
private readonly ProtectedResourceErrorHttpWriter writer = new();
|
||||
|
||||
[Fact]
|
||||
public void WwwAuthenticate_header_with_error_and_description_should_be_a_single_line()
|
||||
{
|
||||
var context = new DefaultHttpContext();
|
||||
|
||||
writer.WriteHttpResponse(
|
||||
new ProtectedResourceErrorResult("oops", "big oops"),
|
||||
context
|
||||
);
|
||||
|
||||
var wwwAuthHeader = context.Response.Headers[HeaderNames.WWWAuthenticate].ToString();
|
||||
wwwAuthHeader.ShouldBe(
|
||||
"""
|
||||
Bearer realm="IdentityServer",error="oops",error_description="big oops"
|
||||
""");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WwwAuthenticate_header_with_error_should_be_a_single_line()
|
||||
{
|
||||
var context = new DefaultHttpContext();
|
||||
|
||||
writer.WriteHttpResponse(
|
||||
new ProtectedResourceErrorResult("oops"),
|
||||
context
|
||||
);
|
||||
|
||||
var wwwAuthHeader = context.Response.Headers[HeaderNames.WWWAuthenticate].ToString();
|
||||
wwwAuthHeader.ShouldBe(
|
||||
"""
|
||||
Bearer realm="IdentityServer",error="oops"
|
||||
""");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WwwAuthenticate_header_should_always_be_a_single_string_value()
|
||||
{
|
||||
var context = new DefaultHttpContext();
|
||||
|
||||
writer.WriteHttpResponse(
|
||||
new ProtectedResourceErrorResult("oops", "big oops"),
|
||||
context
|
||||
);
|
||||
|
||||
var wwwAuthHeader = context.Response.Headers[HeaderNames.WWWAuthenticate];
|
||||
wwwAuthHeader.Count.ShouldBe(1);
|
||||
}
|
||||
}
|
||||
|
|
@ -16,6 +16,7 @@
|
|||
<PackageReference Include="xunit" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" PrivateAssets="All" />
|
||||
<PackageReference Include="FluentAssertions" />
|
||||
<PackageReference Include="Shouldly" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
Loading…
Reference in a new issue