Skip to content

Commit 898bc26

Browse files
Merge branch 'main' into release/is-7.3-rtm
2 parents b95676d + 2e1d64d commit 898bc26

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+1761
-976
lines changed

astro.config.mjs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ export default defineConfig({
3737
integrations: [
3838
starlight({
3939
customCss: ["./src/styles/custom.css"],
40+
routeMiddleware: ["./src/plugins/search-topic-middleware.ts"],
4041
plugins: [
4142
starlightLlmsTxt(),
4243
starlightHeadingBadges(),
@@ -120,7 +121,7 @@ export default defineConfig({
120121
{
121122
icon: "rss",
122123
label: "Blog",
123-
href: "https://blog.duendesoftware.com/",
124+
href: "https://duendesoftware.com/blog",
124125
},
125126
],
126127
components: {

package-lock.json

Lines changed: 179 additions & 136 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,35 +25,35 @@
2525
"postinstall": "patch-package"
2626
},
2727
"dependencies": {
28-
"@astrojs/markdown-remark": "^6.3.1",
29-
"@astrojs/starlight": "^0.34.3",
28+
"@astrojs/markdown-remark": "^6.3.2",
29+
"@astrojs/starlight": "^0.34.4",
3030
"@astrojs/ts-plugin": "^1.10.4",
31-
"@fontsource/roboto": "^5.2.5",
31+
"@fontsource/roboto": "^5.2.6",
3232
"@pasqal-io/starlight-client-mermaid": "^0.1.0",
3333
"@resvg/resvg-js": "^2.6.2",
34-
"astro": "^5.7.13",
35-
"astro-opengraph-images": "^1.12.2",
34+
"astro": "^5.10.1",
35+
"astro-opengraph-images": "^1.13.1",
3636
"astro-redirect-from": "^1.3.3",
3737
"astro-rehype-relative-markdown-links": "^0.18.1",
3838
"jsdom": "^26.0.0",
3939
"patch-package": "^8.0.0",
4040
"react": "^19.0.0",
4141
"rehype-external-links": "^3.0.0",
42-
"satori": "^0.13.1",
43-
"sharp": "^0.34.1",
44-
"starlight-auto-sidebar": "^0.1.1",
42+
"satori": "^0.15.2",
43+
"sharp": "^0.34.2",
44+
"starlight-auto-sidebar": "^0.1.2",
4545
"starlight-giscus": "^0.6.1",
4646
"starlight-heading-badges": "^0.5.0",
47-
"starlight-links-validator": "^0.16.0",
47+
"starlight-links-validator": "^0.17.0",
4848
"starlight-llms-txt": "^0.5.0",
4949
"tw-to-css": "^0.0.12"
5050
},
5151
"devDependencies": {
5252
"@types/jsdom": "^21.1.7",
53-
"@types/node": "^22.15.18",
54-
"@types/react": "^19.1.4",
53+
"@types/node": "^22.15.33",
54+
"@types/react": "^19.1.8",
5555
"node-fetch": "^3.3.2",
56-
"prettier": "3.5.3",
56+
"prettier": "3.6.2",
5757
"prettier-plugin-astro": "^0.14.1"
5858
},
5959
"volta": {
File renamed without changes.

src/components/Banner.astro

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,18 @@ if (!banner) {
1111
}
1212
---
1313

14-
{banner && <div class="sl-banner" set:html={banner.content} />}
14+
{
15+
banner && (
16+
<div class="sl-banner" data-pagefind-ignore set:html={banner.content} />
17+
)
18+
}
1519

1620
<style>
1721
.sl-banner {
18-
--__sl-banner-text: var(--sl-color-banner-text, var(--sl-color-text-invert));
22+
--__sl-banner-text: var(
23+
--sl-color-banner-text,
24+
var(--sl-color-text-invert)
25+
);
1926
padding: var(--sl-nav-pad-y) var(--sl-nav-pad-x);
2027
background-color: var(--sl-color-banner-bg, var(--sl-color-bg-accent));
2128
color: var(--__sl-banner-text);
@@ -27,4 +34,4 @@ if (!banner) {
2734
.sl-banner :global(a) {
2835
color: var(--__sl-banner-text);
2936
}
30-
</style>
37+
</style>

src/components/Newsletter.astro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { Icon } from "@astrojs/starlight/components";
2424
font-size: var(--sl-text-3xl);
2525
font-weight: 500;
2626
svg {
27+
margin-top: 0.5rem;
2728
margin-right: 0.5rem;
2829
}
2930
}

src/components/Pagination.astro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import Default from '@astrojs/starlight/components/Pagination.astro'
2525
a {
2626
gap: 0.5rem;
2727
align-items: center;
28-
text-decoration: none;
28+
text-decoration: underline;
2929
color: var(--sl-color-gray-3);
3030
}
3131
a:hover {
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
label: 'Advanced'
2-
order: 4
2+
order: 10
33
collapsed: true

src/content/docs/accesstokenmanagement/advanced/client-assertions.md

Lines changed: 0 additions & 76 deletions
This file was deleted.
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
---
2+
title: Client Assertions
3+
description: Learn how to use client assertions instead of shared secrets for token client authentication in Duende.AccessTokenManagement.
4+
sidebar:
5+
label: Client Assertions
6+
order: 30
7+
redirect_from:
8+
- /foss/accesstokenmanagement/advanced/client_assertions/
9+
---
10+
import { Code } from "@astrojs/starlight/components";
11+
import { Tabs, TabItem } from "@astrojs/starlight/components";
12+
13+
If your token client is using a client assertion instead of a shared secret, you can provide the assertion in two ways:
14+
15+
* Use the request parameter mechanism to pass a client assertion to the management
16+
* Implement the `IClientAssertionService` interface to centralize client assertion creation
17+
18+
Here's a sample client assertion service using the Microsoft JWT library:
19+
20+
{/* prettier-ignore */}
21+
<Tabs syncKey="atmVersion">
22+
{/* prettier-ignore */}
23+
<TabItem label="V4">
24+
<Code
25+
lang="csharp"
26+
title="ClientAssertionService.cs"
27+
code={`using Duende.AccessTokenManagement;
28+
using Duende.IdentityModel;
29+
using Duende.IdentityModel.Client;
30+
using Microsoft.Extensions.Options;
31+
using Microsoft.IdentityModel.JsonWebTokens;
32+
using Microsoft.IdentityModel.Tokens;
33+
34+
public class ClientAssertionService(IOptionsSnapshot<ClientCredentialsClient> options)
35+
: IClientAssertionService
36+
{
37+
public Task<ClientAssertion?> GetClientAssertionAsync(
38+
ClientCredentialsClientName? clientName = null, TokenRequestParameters? parameters = null)
39+
{
40+
if (clientName == "invoice")
41+
{
42+
var options1 = options.Get(clientName);
43+
44+
var descriptor = new SecurityTokenDescriptor
45+
{
46+
Issuer = options1.ClientId,
47+
Audience = options1.TokenEndpoint,
48+
Expires = DateTime.UtcNow.AddMinutes(1),
49+
SigningCredentials = GetSigningCredential(),
50+
51+
Claims = new Dictionary<string, object>
52+
{
53+
{ JwtClaimTypes.JwtId, Guid.NewGuid().ToString() },
54+
{ JwtClaimTypes.Subject, options1.ClientId! },
55+
{ JwtClaimTypes.IssuedAt, DateTime.UtcNow.ToEpochTime() }
56+
},
57+
58+
AdditionalHeaderClaims = new Dictionary<string, object>
59+
{
60+
{ JwtClaimTypes.TokenType, "client-authentication+jwt" }
61+
}
62+
};
63+
64+
var handler = new JsonWebTokenHandler();
65+
var jwt = handler.CreateToken(descriptor);
66+
67+
return Task.FromResult<ClientAssertion?>(new ClientAssertion
68+
{
69+
Type = OidcConstants.ClientAssertionTypes.JwtBearer,
70+
Value = jwt
71+
});
72+
}
73+
74+
return Task.FromResult<ClientAssertion?>(null);
75+
}
76+
77+
private SigningCredentials GetSigningCredential()
78+
{
79+
throw new NotImplementedException();
80+
}
81+
}`}/>
82+
</TabItem>
83+
<TabItem label="V3">
84+
85+
<Code
86+
lang="csharp"
87+
title="ClientAssertionService.cs"
88+
code={`using Duende.AccessTokenManagement;
89+
using Duende.IdentityModel;
90+
using Duende.IdentityModel.Client;
91+
using Microsoft.Extensions.Options;
92+
using Microsoft.IdentityModel.JsonWebTokens;
93+
using Microsoft.IdentityModel.Tokens;
94+
95+
public class ClientAssertionService(IOptionsSnapshot<ClientCredentialsClient> options)
96+
: IClientAssertionService
97+
{
98+
public Task<ClientAssertion?> GetClientAssertionAsync(
99+
string? clientName = null, TokenRequestParameters? parameters = null)
100+
{
101+
if (clientName == "invoice")
102+
{
103+
var options1 = options.Get(clientName);
104+
105+
var descriptor = new SecurityTokenDescriptor
106+
{
107+
Issuer = options1.ClientId,
108+
Audience = options1.TokenEndpoint,
109+
Expires = DateTime.UtcNow.AddMinutes(1),
110+
SigningCredentials = GetSigningCredential(),
111+
112+
Claims = new Dictionary<string, object>
113+
{
114+
{ JwtClaimTypes.JwtId, Guid.NewGuid().ToString() },
115+
{ JwtClaimTypes.Subject, options1.ClientId! },
116+
{ JwtClaimTypes.IssuedAt, DateTime.UtcNow.ToEpochTime() }
117+
},
118+
119+
AdditionalHeaderClaims = new Dictionary<string, object>
120+
{
121+
{ JwtClaimTypes.TokenType, "client-authentication+jwt" }
122+
}
123+
};
124+
125+
var handler = new JsonWebTokenHandler();
126+
var jwt = handler.CreateToken(descriptor);
127+
128+
return Task.FromResult<ClientAssertion?>(new ClientAssertion
129+
{
130+
Type = OidcConstants.ClientAssertionTypes.JwtBearer,
131+
Value = jwt
132+
});
133+
}
134+
135+
return Task.FromResult<ClientAssertion?>(null);
136+
}
137+
138+
private SigningCredentials GetSigningCredential()
139+
{
140+
throw new NotImplementedException();
141+
}
142+
}`}/>
143+
</TabItem>
144+
</Tabs>

0 commit comments

Comments
 (0)