Browse Source

Use a crypto-secure RNG to generate the request_id parameter

pull/480/head
Kévin Chalet 9 years ago
parent
commit
dbfd9f58ab
  1. 8
      src/OpenIddict/OpenIddictProvider.Authentication.cs
  2. 8
      src/OpenIddict/OpenIddictProvider.Session.cs
  3. 6
      test/OpenIddict.Tests/OpenIddictProviderTests.Authentication.cs
  4. 6
      test/OpenIddict.Tests/OpenIddictProviderTests.Session.cs

8
src/OpenIddict/OpenIddictProvider.Authentication.cs

@ -15,6 +15,7 @@ using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.WebUtilities; using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Bson; using Newtonsoft.Json.Bson;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
@ -306,9 +307,10 @@ namespace OpenIddict
// to flow across requests and internal/external authentication/registration workflows. // to flow across requests and internal/external authentication/registration workflows.
if (options.EnableRequestCaching && string.IsNullOrEmpty(context.Request.RequestId)) if (options.EnableRequestCaching && string.IsNullOrEmpty(context.Request.RequestId))
{ {
// Generate a request identifier. Note: using a crypto-secure // Generate a 256-bit request identifier using a crypto-secure random number generator.
// random number generator is not necessary in this case. var bytes = new byte[256 / 8];
context.Request.RequestId = Guid.NewGuid().ToString(); options.RandomNumberGenerator.GetBytes(bytes);
context.Request.RequestId = Base64UrlEncoder.Encode(bytes);
// Store the serialized authorization request parameters in the distributed cache. // Store the serialized authorization request parameters in the distributed cache.
var stream = new MemoryStream(); var stream = new MemoryStream();

8
src/OpenIddict/OpenIddictProvider.Session.cs

@ -14,6 +14,7 @@ using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.WebUtilities; using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Bson; using Newtonsoft.Json.Bson;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
@ -133,9 +134,10 @@ namespace OpenIddict
// to make it easier to flow across requests and internal/external logout workflows. // to make it easier to flow across requests and internal/external logout workflows.
if (options.EnableRequestCaching && string.IsNullOrEmpty(context.Request.RequestId)) if (options.EnableRequestCaching && string.IsNullOrEmpty(context.Request.RequestId))
{ {
// Generate a request identifier. Note: using a crypto-secure // Generate a 256-bit request identifier using a crypto-secure random number generator.
// random number generator is not necessary in this case. var bytes = new byte[256 / 8];
context.Request.RequestId = Guid.NewGuid().ToString(); options.RandomNumberGenerator.GetBytes(bytes);
context.Request.RequestId = Base64UrlEncoder.Encode(bytes);
// Store the serialized logout request parameters in the distributed cache. // Store the serialized logout request parameters in the distributed cache.
var stream = new MemoryStream(); var stream = new MemoryStream();

6
test/OpenIddict.Tests/OpenIddictProviderTests.Authentication.cs

@ -5,6 +5,7 @@
*/ */
using System.IO; using System.IO;
using System.Security.Cryptography;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using AspNet.Security.OpenIdConnect.Client; using AspNet.Security.OpenIdConnect.Client;
@ -435,6 +436,7 @@ namespace OpenIddict.Tests
{ {
// Arrange // Arrange
var cache = new Mock<IDistributedCache>(); var cache = new Mock<IDistributedCache>();
var generator = new Mock<RandomNumberGenerator>();
var server = CreateAuthorizationServer(builder => var server = CreateAuthorizationServer(builder =>
{ {
@ -455,6 +457,8 @@ namespace OpenIddict.Tests
builder.Services.AddSingleton(cache.Object); builder.Services.AddSingleton(cache.Object);
builder.EnableRequestCaching(); builder.EnableRequestCaching();
builder.Configure(options => options.RandomNumberGenerator = generator.Object);
}); });
var client = new OpenIdConnectClient(server.CreateClient()); var client = new OpenIdConnectClient(server.CreateClient());
@ -478,6 +482,8 @@ namespace OpenIddict.Tests
It.IsAny<byte[]>(), It.IsAny<byte[]>(),
It.IsAny<DistributedCacheEntryOptions>(), It.IsAny<DistributedCacheEntryOptions>(),
It.IsAny<CancellationToken>()), Times.Once()); It.IsAny<CancellationToken>()), Times.Once());
generator.Verify(mock => mock.GetBytes(It.Is<byte[]>(bytes => bytes.Length == 256 / 8)), Times.Once());
} }
[Theory] [Theory]

6
test/OpenIddict.Tests/OpenIddictProviderTests.Session.cs

@ -4,6 +4,7 @@
* the license and the contributors participating to this project. * the license and the contributors participating to this project.
*/ */
using System.Security.Cryptography;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using AspNet.Security.OpenIdConnect.Client; using AspNet.Security.OpenIdConnect.Client;
@ -119,6 +120,7 @@ namespace OpenIddict.Tests
{ {
// Arrange // Arrange
var cache = new Mock<IDistributedCache>(); var cache = new Mock<IDistributedCache>();
var generator = new Mock<RandomNumberGenerator>();
var server = CreateAuthorizationServer(builder => var server = CreateAuthorizationServer(builder =>
{ {
@ -131,6 +133,8 @@ namespace OpenIddict.Tests
builder.Services.AddSingleton(cache.Object); builder.Services.AddSingleton(cache.Object);
builder.EnableRequestCaching(); builder.EnableRequestCaching();
builder.Configure(options => options.RandomNumberGenerator = generator.Object);
}); });
var client = new OpenIdConnectClient(server.CreateClient()); var client = new OpenIdConnectClient(server.CreateClient());
@ -152,6 +156,8 @@ namespace OpenIddict.Tests
It.IsAny<byte[]>(), It.IsAny<byte[]>(),
It.IsAny<DistributedCacheEntryOptions>(), It.IsAny<DistributedCacheEntryOptions>(),
It.IsAny<CancellationToken>()), Times.Once()); It.IsAny<CancellationToken>()), Times.Once());
generator.Verify(mock => mock.GetBytes(It.Is<byte[]>(bytes => bytes.Length == 256 / 8)), Times.Once());
} }
[Fact] [Fact]

Loading…
Cancel
Save