From 91f3211517b02869187b9f7fa34b4769bdeb457c Mon Sep 17 00:00:00 2001 From: Brock Allen Date: Mon, 30 Mar 2020 12:14:41 -0400 Subject: [PATCH] Improve query on cors origins. #3395 (#4203) --- .../migrations/SqlServer/createdb.bat | 2 ++ .../src/DbContexts/ConfigurationDbContext.cs | 8 +++++ .../src/Interfaces/IConfigurationDbContext.cs | 8 +++++ .../host/Properties/launchSettings.json | 1 + .../SqlServer/Configuration/ClientsConsole.cs | 24 ++++++-------- .../SqlServer/Configuration/ClientsWeb.cs | 8 ++--- .../SqlServer/Configuration/Resources.cs | 32 ++++--------------- .../src/Services/CorsPolicyService.cs | 17 ++++------ 8 files changed, 47 insertions(+), 53 deletions(-) create mode 100644 src/EntityFramework.Storage/migrations/SqlServer/createdb.bat diff --git a/src/EntityFramework.Storage/migrations/SqlServer/createdb.bat b/src/EntityFramework.Storage/migrations/SqlServer/createdb.bat new file mode 100644 index 0000000000..968593e8a4 --- /dev/null +++ b/src/EntityFramework.Storage/migrations/SqlServer/createdb.bat @@ -0,0 +1,2 @@ +dotnet ef database update -c PersistedGrantDbContext +dotnet ef database update -c ConfigurationDbContext diff --git a/src/EntityFramework.Storage/src/DbContexts/ConfigurationDbContext.cs b/src/EntityFramework.Storage/src/DbContexts/ConfigurationDbContext.cs index 64f458185b..08d6ded278 100644 --- a/src/EntityFramework.Storage/src/DbContexts/ConfigurationDbContext.cs +++ b/src/EntityFramework.Storage/src/DbContexts/ConfigurationDbContext.cs @@ -61,6 +61,14 @@ public ConfigurationDbContext(DbContextOptions options, ConfigurationS /// public DbSet Clients { get; set; } + /// + /// Gets or sets the clients' CORS origins. + /// + /// + /// The clients CORS origins. + /// + public DbSet ClientCorsOrigins { get; set; } + /// /// Gets or sets the identity resources. /// diff --git a/src/EntityFramework.Storage/src/Interfaces/IConfigurationDbContext.cs b/src/EntityFramework.Storage/src/Interfaces/IConfigurationDbContext.cs index f2626a7226..81d075f7ea 100644 --- a/src/EntityFramework.Storage/src/Interfaces/IConfigurationDbContext.cs +++ b/src/EntityFramework.Storage/src/Interfaces/IConfigurationDbContext.cs @@ -21,6 +21,14 @@ public interface IConfigurationDbContext : IDisposable /// The clients. /// DbSet Clients { get; set; } + + /// + /// Gets or sets the clients' CORS origins. + /// + /// + /// The clients CORS origins. + /// + DbSet ClientCorsOrigins { get; set; } /// /// Gets or sets the identity resources. diff --git a/src/EntityFramework/host/Properties/launchSettings.json b/src/EntityFramework/host/Properties/launchSettings.json index 5bf60a18dd..e41dbca000 100644 --- a/src/EntityFramework/host/Properties/launchSettings.json +++ b/src/EntityFramework/host/Properties/launchSettings.json @@ -10,6 +10,7 @@ "profiles": { "Host": { "commandName": "Project", + "launchBrowser": true, "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" }, diff --git a/src/EntityFramework/migrations/SqlServer/Configuration/ClientsConsole.cs b/src/EntityFramework/migrations/SqlServer/Configuration/ClientsConsole.cs index 6571503171..6db0410106 100644 --- a/src/EntityFramework/migrations/SqlServer/Configuration/ClientsConsole.cs +++ b/src/EntityFramework/migrations/SqlServer/Configuration/ClientsConsole.cs @@ -26,7 +26,7 @@ public static IEnumerable Get() ClientId = "client", ClientSecrets = {new Secret("secret".Sha256())}, AllowedGrantTypes = GrantTypes.ClientCredentials, - AllowedScopes = {"api1", "api2.read_only", IdentityServerConstants.LocalApi.ScopeName} + AllowedScopes = { "feature1", "feature2", IdentityServerConstants.LocalApi.ScopeName} }, /////////////////////////////////////////// @@ -48,7 +48,7 @@ public static IEnumerable Get() }, AccessTokenType = AccessTokenType.Jwt, AllowedGrantTypes = GrantTypes.ClientCredentials, - AllowedScopes = {"api1", "api2.read_only"} + AllowedScopes = { "feature1", "feature2" } }, /////////////////////////////////////////// @@ -73,7 +73,7 @@ public static IEnumerable Get() } }, AllowedGrantTypes = GrantTypes.ClientCredentials, - AllowedScopes = {"api1", "api2.read_only"} + AllowedScopes = { "feature1", "feature2" } }, /////////////////////////////////////////// @@ -84,7 +84,7 @@ public static IEnumerable Get() ClientId = "client.custom", ClientSecrets = {new Secret("secret".Sha256())}, AllowedGrantTypes = {"custom", "custom.nosubject"}, - AllowedScopes = {"api1", "api2.read_only"} + AllowedScopes = { "feature1", "feature2" } }, /////////////////////////////////////////// @@ -100,8 +100,7 @@ public static IEnumerable Get() { IdentityServerConstants.StandardScopes.OpenId, "custom.profile", - "api1", - "api2.read_only" + "feature1", "feature2" } }, @@ -118,8 +117,7 @@ public static IEnumerable Get() { IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Email, - "api1", - "api2.read_only" + "feature1", "feature2" } }, @@ -140,8 +138,7 @@ public static IEnumerable Get() IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile, IdentityServerConstants.StandardScopes.Email, - "api1", - "api2.read_only" + "feature1", "feature2" } }, /////////////////////////////////////////// @@ -163,8 +160,7 @@ public static IEnumerable Get() IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile, IdentityServerConstants.StandardScopes.Email, - "api1", - "api2.read_only" + "feature1", "feature2" } }, @@ -177,7 +173,7 @@ public static IEnumerable Get() ClientId = "roclient.reference", ClientSecrets = {new Secret("secret".Sha256())}, AllowedGrantTypes = GrantTypes.ResourceOwnerPassword, - AllowedScopes = {"api1", "api2.read_only"}, + AllowedScopes = {"feature1", "feature2"}, AccessTokenType = AccessTokenType.Reference }, @@ -201,7 +197,7 @@ public static IEnumerable Get() IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile, IdentityServerConstants.StandardScopes.Email, - "api1", "api2.read_only", "api2.full_access" + "feature1", "feature2" } } }; diff --git a/src/EntityFramework/migrations/SqlServer/Configuration/ClientsWeb.cs b/src/EntityFramework/migrations/SqlServer/Configuration/ClientsWeb.cs index e33157e080..6b9ed78f1e 100644 --- a/src/EntityFramework/migrations/SqlServer/Configuration/ClientsWeb.cs +++ b/src/EntityFramework/migrations/SqlServer/Configuration/ClientsWeb.cs @@ -41,7 +41,7 @@ public static IEnumerable Get() IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile, IdentityServerConstants.StandardScopes.Email, - "api1", "api2.read_only", "api2.full_access" + "feature1", "feature2" } }, @@ -73,7 +73,7 @@ public static IEnumerable Get() IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile, IdentityServerConstants.StandardScopes.Email, - "api1", "api2.read_only" + "feature1", "feature2" } }, @@ -105,7 +105,7 @@ public static IEnumerable Get() IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile, IdentityServerConstants.StandardScopes.Email, - "api1", "api2.read_only" + "feature1", "feature2" } }, @@ -137,7 +137,7 @@ public static IEnumerable Get() IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile, IdentityServerConstants.StandardScopes.Email, - "api1", "api2.read_only" + "feature1", "feature2" } } }; diff --git a/src/EntityFramework/migrations/SqlServer/Configuration/Resources.cs b/src/EntityFramework/migrations/SqlServer/Configuration/Resources.cs index 752a532fca..64d78e41c9 100644 --- a/src/EntityFramework/migrations/SqlServer/Configuration/Resources.cs +++ b/src/EntityFramework/migrations/SqlServer/Configuration/Resources.cs @@ -28,12 +28,12 @@ public class Resources // simple version with ctor new ApiResource("api1", "Some API 1") { - // this is needed for introspection when using reference tokens - ApiSecrets = { new Secret("secret".Sha256()) }, + //// this is needed for introspection when using reference tokens + //ApiSecrets = { new Secret("secret".Sha256()) }, //AllowedSigningAlgorithms = { "RS256", "ES256" } - Scopes = { "api1" } + Scopes = { "feature1" } }, // expanded version if more control is needed @@ -54,35 +54,17 @@ public class Resources JwtClaimTypes.Email }, - Scopes = { "api2.full_access", "api2.read_only", "api2.internal" } + Scopes = { "feature2", "feature3" } } }; public static IEnumerable ApiScopes = new[] { // local API - // todo: dom, should we also use a resource id for this? new ApiScope(LocalApi.ScopeName), - new ApiScope("api1"), - new ApiScope - { - Name = "api2.full_access", - DisplayName = "Full access to API 2" - }, - new ApiScope - { - Name = "api2.read_only", - DisplayName = "Read only access to API 2" - }, - new ApiScope - { - Name = "api2.internal", - ShowInDiscoveryDocument = false, - UserClaims = - { - "internal_id" - } - }, + new ApiScope("feature1"), + new ApiScope("feature2"), + new ApiScope("feature3"), new ApiScope { Name = "transaction" diff --git a/src/EntityFramework/src/Services/CorsPolicyService.cs b/src/EntityFramework/src/Services/CorsPolicyService.cs index 8b517d0888..a1fd10fda3 100644 --- a/src/EntityFramework/src/Services/CorsPolicyService.cs +++ b/src/EntityFramework/src/Services/CorsPolicyService.cs @@ -42,19 +42,16 @@ public CorsPolicyService(IHttpContextAccessor context, ILogger public async Task IsOriginAllowedAsync(string origin) { - // doing this here and not in the ctor because: https://github.com/aspnet/CORS/issues/105 - var dbContext = _context.HttpContext.RequestServices.GetRequiredService(); - origin = origin.ToLowerInvariant(); - var origins = await dbContext.Clients.AsNoTracking() - .Include(x => x.AllowedCorsOrigins).AsNoTracking() - .SelectMany(x => x.AllowedCorsOrigins.Select(y => y.Origin)) - .ToListAsync(); - - var distinctOrigins = origins.Where(x => x != null).Distinct(); + // doing this here and not in the ctor because: https://github.com/aspnet/CORS/issues/105 + var dbContext = _context.HttpContext.RequestServices.GetRequiredService(); - var isAllowed = distinctOrigins.Contains(origin, StringComparer.OrdinalIgnoreCase); + var query = from o in dbContext.ClientCorsOrigins + where o.Origin == origin + select o; + + var isAllowed = await query.AnyAsync(); _logger.LogDebug("Origin {origin} is allowed: {originAllowed}", origin, isAllowed);