diff --git a/src/OpenIddict/OpenIddictProvider.Authentication.cs b/src/OpenIddict/OpenIddictProvider.Authentication.cs index 8cea3b45..cc3035b3 100644 --- a/src/OpenIddict/OpenIddictProvider.Authentication.cs +++ b/src/OpenIddict/OpenIddictProvider.Authentication.cs @@ -16,6 +16,7 @@ using Microsoft.AspNetCore.WebUtilities; using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using Microsoft.IdentityModel.Tokens; using Newtonsoft.Json; using Newtonsoft.Json.Bson; using Newtonsoft.Json.Linq; @@ -312,9 +313,10 @@ namespace OpenIddict // to flow across requests and internal/external authentication/registration workflows. if (options.EnableRequestCaching && string.IsNullOrEmpty(context.Request.RequestId)) { - // Generate a request identifier. Note: using a crypto-secure - // random number generator is not necessary in this case. - context.Request.RequestId = Guid.NewGuid().ToString(); + // Generate a 256-bit request identifier using a crypto-secure random number generator. + var bytes = new byte[256 / 8]; + options.RandomNumberGenerator.GetBytes(bytes); + context.Request.RequestId = Base64UrlEncoder.Encode(bytes); // Store the serialized authorization request parameters in the distributed cache. var stream = new MemoryStream(); diff --git a/src/OpenIddict/OpenIddictProvider.Session.cs b/src/OpenIddict/OpenIddictProvider.Session.cs index 83f56e47..016c4a83 100644 --- a/src/OpenIddict/OpenIddictProvider.Session.cs +++ b/src/OpenIddict/OpenIddictProvider.Session.cs @@ -15,6 +15,7 @@ using Microsoft.AspNetCore.WebUtilities; using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using Microsoft.IdentityModel.Tokens; using Newtonsoft.Json; using Newtonsoft.Json.Bson; using Newtonsoft.Json.Linq; @@ -139,9 +140,10 @@ namespace OpenIddict // to make it easier to flow across requests and internal/external logout workflows. if (options.EnableRequestCaching && string.IsNullOrEmpty(context.Request.RequestId)) { - // Generate a request identifier. Note: using a crypto-secure - // random number generator is not necessary in this case. - context.Request.RequestId = Guid.NewGuid().ToString(); + // Generate a 256-bit request identifier using a crypto-secure random number generator. + var bytes = new byte[256 / 8]; + options.RandomNumberGenerator.GetBytes(bytes); + context.Request.RequestId = Base64UrlEncoder.Encode(bytes); // Store the serialized logout request parameters in the distributed cache. var stream = new MemoryStream(); diff --git a/test/OpenIddict.Tests/OpenIddictProviderTests.Authentication.cs b/test/OpenIddict.Tests/OpenIddictProviderTests.Authentication.cs index 3eaab432..92e3833c 100644 --- a/test/OpenIddict.Tests/OpenIddictProviderTests.Authentication.cs +++ b/test/OpenIddict.Tests/OpenIddictProviderTests.Authentication.cs @@ -5,6 +5,7 @@ */ using System.IO; +using System.Security.Cryptography; using System.Threading; using System.Threading.Tasks; using AspNet.Security.OpenIdConnect.Client; @@ -436,6 +437,7 @@ namespace OpenIddict.Tests { // Arrange var cache = new Mock(); + var generator = new Mock(); var server = CreateAuthorizationServer(builder => { @@ -456,6 +458,8 @@ namespace OpenIddict.Tests builder.Services.AddSingleton(cache.Object); builder.EnableRequestCaching(); + + builder.Configure(options => options.RandomNumberGenerator = generator.Object); }); var client = new OpenIdConnectClient(server.CreateClient()); @@ -478,6 +482,8 @@ namespace OpenIddict.Tests OpenIddictConstants.Environment.AuthorizationRequest + identifier, It.IsAny(), It.IsAny()), Times.Once()); + + generator.Verify(mock => mock.GetBytes(It.Is(bytes => bytes.Length == 256 / 8)), Times.Once()); } [Theory] diff --git a/test/OpenIddict.Tests/OpenIddictProviderTests.Session.cs b/test/OpenIddict.Tests/OpenIddictProviderTests.Session.cs index ff53564d..cf0544a0 100644 --- a/test/OpenIddict.Tests/OpenIddictProviderTests.Session.cs +++ b/test/OpenIddict.Tests/OpenIddictProviderTests.Session.cs @@ -4,6 +4,7 @@ * the license and the contributors participating to this project. */ +using System.Security.Cryptography; using System.Threading; using System.Threading.Tasks; using AspNet.Security.OpenIdConnect.Client; @@ -120,6 +121,7 @@ namespace OpenIddict.Tests { // Arrange var cache = new Mock(); + var generator = new Mock(); var server = CreateAuthorizationServer(builder => { @@ -132,6 +134,8 @@ namespace OpenIddict.Tests builder.Services.AddSingleton(cache.Object); builder.EnableRequestCaching(); + + builder.Configure(options => options.RandomNumberGenerator = generator.Object); }); var client = new OpenIdConnectClient(server.CreateClient()); @@ -152,6 +156,8 @@ namespace OpenIddict.Tests OpenIddictConstants.Environment.LogoutRequest + identifier, It.IsAny(), It.IsAny()), Times.Once()); + + generator.Verify(mock => mock.GetBytes(It.Is(bytes => bytes.Length == 256 / 8)), Times.Once()); } [Fact]