Skip to content

Commit

Permalink
Merge pull request #1662 from DuendeSoftware/joe/reference-token-filt…
Browse files Browse the repository at this point in the history
…ering

Filter protocol claims from reference tokens
  • Loading branch information
josephdecock authored Dec 9, 2024
2 parents 6d5e47e + 305f0f9 commit bb383dd
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 1 deletion.
7 changes: 6 additions & 1 deletion src/IdentityServer/Validation/Default/TokenValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,12 @@ private IEnumerable<Claim> ReferenceTokenToClaims(Token token)
claims.Add(new Claim(JwtClaimTypes.Audience, aud));
}

claims.AddRange(token.Claims);
claims.AddRange(token.Claims.Where(c =>
c.Type != JwtClaimTypes.IssuedAt &&
c.Type != JwtClaimTypes.Issuer &&
c.Type != JwtClaimTypes.NotBefore &&
c.Type != JwtClaimTypes.Expiration
));
return claims;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@


using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Threading.Tasks;
using Duende.IdentityModel;
using Duende.IdentityServer.Models;
using Duende.IdentityServer.Stores;
using Duende.IdentityServer.Validation;
Expand Down Expand Up @@ -115,4 +117,76 @@ public async Task invalid_token_should_return_inactive()
result.Claims.Should().BeNull();
result.Token.Should().Be("invalid");
}

[Theory]
[MemberData(nameof(DuplicateClaimTestCases))]
[Trait("Category", Category)]
public async Task protocol_claims_should_not_be_duplicated(
string claimType,
System.Security.Claims.Claim duplicateClaim,
Func<Token, string> expectedValueSelector)
{
var token = new Token
{
CreationTime = DateTime.UtcNow,
Issuer = "http://op",
ClientId = "codeclient",
Lifetime = 1000,
Claims =
{
duplicateClaim
}
};

var handle = await _referenceTokenStore.StoreReferenceTokenAsync(token);
var param = new NameValueCollection
{
{ "token", handle }
};

var result = await _subject.ValidateAsync(
new IntrospectionRequestValidationContext
{
Parameters = param,
Api = new ApiResource("api")
}
);

result.Claims.Where(c => c.Type == claimType)
.Should()
.HaveCount(1)
.And
.Contain(c => c.Value == expectedValueSelector(token));
}

public static IEnumerable<object[]> DuplicateClaimTestCases()
{
yield return new object[]
{
JwtClaimTypes.IssuedAt,
new System.Security.Claims.Claim(JwtClaimTypes.IssuedAt, "1234"),
(Func<Token, string>)(token => new DateTimeOffset(token.CreationTime).ToUnixTimeSeconds().ToString())
};

yield return new object[]
{
JwtClaimTypes.Issuer,
new System.Security.Claims.Claim(JwtClaimTypes.Issuer, "https://bogus.example.com"),
(Func<Token, string>)(token => token.Issuer)
};

yield return new object[]
{
JwtClaimTypes.NotBefore,
new System.Security.Claims.Claim(JwtClaimTypes.NotBefore, "1234"),
(Func<Token, string>)(token => new DateTimeOffset(token.CreationTime).ToUnixTimeSeconds().ToString())
};

yield return new object[]
{
JwtClaimTypes.Expiration,
new System.Security.Claims.Claim(JwtClaimTypes.Expiration, "1234"),
(Func<Token, string>)(token => new DateTimeOffset(token.CreationTime).AddSeconds(token.Lifetime).ToUnixTimeSeconds().ToString())
};
}
}

0 comments on commit bb383dd

Please sign in to comment.