Skip to content

Commit c98a9cc

Browse files
authored
Fix IDX21323: RequireNonce is 'False' during token refreshClient (#240)
1 parent 8ff9eea commit c98a9cc

File tree

2 files changed

+14
-14
lines changed

2 files changed

+14
-14
lines changed

8.0/BlazorWebAppOidc/BlazorWebAppOidc/CookieOidcRefresher.cs

+7-7
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@
1212
namespace BlazorWebAppOidc;
1313

1414
// https://github.com/dotnet/aspnetcore/issues/8175
15-
internal sealed class CookieOidcRefresher(IOptionsMonitor<OpenIdConnectOptions> oidcOptionsMonitor) : IDisposable
15+
internal sealed class CookieOidcRefresher(IOptionsMonitor<OpenIdConnectOptions> oidcOptionsMonitor)
1616
{
17-
private readonly HttpClient refreshClient = new();
1817
private readonly OpenIdConnectProtocolValidator oidcTokenValidator = new()
1918
{
20-
// Refresh requests do not use the nonce parameter. Otherwise, we'd use oidcOptions.ProtocolValidator.
19+
// We no longer have the original nonce cookie which is deleted at the end of the authorization code flow having served its purpose.
20+
// Even if we had the nonce, it's likely expired. It's not intended for refresh requests. Otherwise, we'd use oidcOptions.ProtocolValidator.
2121
RequireNonce = false,
2222
};
2323

@@ -39,7 +39,7 @@ public async Task ValidateOrRefreshCookieAsync(CookieValidatePrincipalContext va
3939
var oidcConfiguration = await oidcOptions.ConfigurationManager!.GetConfigurationAsync(validateContext.HttpContext.RequestAborted);
4040
var tokenEndpoint = oidcConfiguration.TokenEndpoint ?? throw new InvalidOperationException("Cannot refresh cookie. TokenEndpoint missing!");
4141

42-
using var refreshResponse = await refreshClient.PostAsync(tokenEndpoint,
42+
using var refreshResponse = await oidcOptions.Backchannel.PostAsync(tokenEndpoint,
4343
new FormUrlEncodedContent(new Dictionary<string, string?>()
4444
{
4545
["grant_type"] = "refresh_token",
@@ -77,11 +77,13 @@ public async Task ValidateOrRefreshCookieAsync(CookieValidatePrincipalContext va
7777
return;
7878
}
7979

80+
var validatedIdToken = JwtSecurityTokenConverter.Convert(validationResult.SecurityToken as JsonWebToken);
81+
validatedIdToken.Payload["nonce"] = null;
8082
oidcTokenValidator.ValidateTokenResponse(new()
8183
{
8284
ProtocolMessage = message,
8385
ClientId = oidcOptions.ClientId,
84-
ValidatedIdToken = JwtSecurityTokenConverter.Convert(validationResult.SecurityToken as JsonWebToken),
86+
ValidatedIdToken = validatedIdToken,
8587
});
8688

8789
validateContext.ShouldRenew = true;
@@ -97,6 +99,4 @@ public async Task ValidateOrRefreshCookieAsync(CookieValidatePrincipalContext va
9799
new() { Name = "expires_at", Value = expiresAt.ToString("o", CultureInfo.InvariantCulture) },
98100
]);
99101
}
100-
101-
public void Dispose() => refreshClient.Dispose();
102102
}

8.0/BlazorWebAppOidcBff/BlazorWebAppOidc/CookieOidcRefresher.cs

+7-7
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@
1212
namespace BlazorWebAppOidc;
1313

1414
// https://github.com/dotnet/aspnetcore/issues/8175
15-
internal sealed class CookieOidcRefresher(IOptionsMonitor<OpenIdConnectOptions> oidcOptionsMonitor) : IDisposable
15+
internal sealed class CookieOidcRefresher(IOptionsMonitor<OpenIdConnectOptions> oidcOptionsMonitor)
1616
{
17-
private readonly HttpClient refreshClient = new();
1817
private readonly OpenIdConnectProtocolValidator oidcTokenValidator = new()
1918
{
20-
// Refresh requests do not use the nonce parameter. Otherwise, we'd use oidcOptions.ProtocolValidator.
19+
// We no longer have the original nonce cookie which is deleted at the end of the authorization code flow having served its purpose.
20+
// Even if we had the nonce, it's likely expired. It's not intended for refresh requests. Otherwise, we'd use oidcOptions.ProtocolValidator.
2121
RequireNonce = false,
2222
};
2323

@@ -39,7 +39,7 @@ public async Task ValidateOrRefreshCookieAsync(CookieValidatePrincipalContext va
3939
var oidcConfiguration = await oidcOptions.ConfigurationManager!.GetConfigurationAsync(validateContext.HttpContext.RequestAborted);
4040
var tokenEndpoint = oidcConfiguration.TokenEndpoint ?? throw new InvalidOperationException("Cannot refresh cookie. TokenEndpoint missing!");
4141

42-
using var refreshResponse = await refreshClient.PostAsync(tokenEndpoint,
42+
using var refreshResponse = await oidcOptions.Backchannel.PostAsync(tokenEndpoint,
4343
new FormUrlEncodedContent(new Dictionary<string, string?>()
4444
{
4545
["grant_type"] = "refresh_token",
@@ -77,11 +77,13 @@ public async Task ValidateOrRefreshCookieAsync(CookieValidatePrincipalContext va
7777
return;
7878
}
7979

80+
var validatedIdToken = JwtSecurityTokenConverter.Convert(validationResult.SecurityToken as JsonWebToken);
81+
validatedIdToken.Payload["nonce"] = null;
8082
oidcTokenValidator.ValidateTokenResponse(new()
8183
{
8284
ProtocolMessage = message,
8385
ClientId = oidcOptions.ClientId,
84-
ValidatedIdToken = JwtSecurityTokenConverter.Convert(validationResult.SecurityToken as JsonWebToken),
86+
ValidatedIdToken = validatedIdToken,
8587
});
8688

8789
validateContext.ShouldRenew = true;
@@ -97,6 +99,4 @@ public async Task ValidateOrRefreshCookieAsync(CookieValidatePrincipalContext va
9799
new() { Name = "expires_at", Value = expiresAt.ToString("o", CultureInfo.InvariantCulture) },
98100
]);
99101
}
100-
101-
public void Dispose() => refreshClient.Dispose();
102102
}

0 commit comments

Comments
 (0)