@ -0,0 +1,96 @@ | |||||
namespace DataProtectionExtensions | |||||
{ | |||||
using System; | |||||
using System.Linq; | |||||
using System.Security.Cryptography.X509Certificates; | |||||
using Microsoft.AspNetCore.DataProtection; | |||||
using Microsoft.AspNetCore.DataProtection.Repositories; | |||||
using Microsoft.AspNetCore.DataProtection.XmlEncryption; | |||||
using Microsoft.Extensions.DependencyInjection; | |||||
using Microsoft.Extensions.Logging; | |||||
using System.Net; | |||||
/// <summary> | |||||
/// Extension methods for <see cref="IDataProtectionBuilder"/> for configuring | |||||
/// data protection options. | |||||
/// </summary> | |||||
public static class DataProtectionBuilderExtensions | |||||
{ | |||||
/// <summary> | |||||
/// Sets up data protection to persist session keys in Redis. | |||||
/// </summary> | |||||
/// <param name="builder">The <see cref="IDataProtectionBuilder"/> used to set up data protection options.</param> | |||||
/// <param name="redisConnectionString">The connection string specifying the Redis instance and database for key storage.</param> | |||||
/// <returns> | |||||
/// The <paramref name="builder" /> for continued configuration. | |||||
/// </returns> | |||||
/// <exception cref="System.ArgumentNullException"> | |||||
/// Thrown if <paramref name="builder" /> or <paramref name="redisConnectionString" /> is <see langword="null" />. | |||||
/// </exception> | |||||
/// <exception cref="System.ArgumentException"> | |||||
/// Thrown if <paramref name="redisConnectionString" /> is empty. | |||||
/// </exception> | |||||
public static IDataProtectionBuilder PersistKeysToRedis(this IDataProtectionBuilder builder, string redisConnectionString) | |||||
{ | |||||
if (builder == null) | |||||
{ | |||||
throw new ArgumentNullException(nameof(builder)); | |||||
} | |||||
if (redisConnectionString == null) | |||||
{ | |||||
throw new ArgumentNullException(nameof(redisConnectionString)); | |||||
} | |||||
if (redisConnectionString.Length == 0) | |||||
{ | |||||
throw new ArgumentException("Redis connection string may not be empty.", nameof(redisConnectionString)); | |||||
} | |||||
var ips = Dns.GetHostAddressesAsync(redisConnectionString).Result; | |||||
return builder.Use(ServiceDescriptor.Singleton<IXmlRepository>(services => new RedisXmlRepository(ips.First().ToString(), services.GetRequiredService<ILogger<RedisXmlRepository>>()))); | |||||
} | |||||
/// <summary> | |||||
/// Updates an <see cref="IDataProtectionBuilder"/> to use the service of | |||||
/// a specific type, removing all other services of that type. | |||||
/// </summary> | |||||
/// <param name="builder">The <see cref="IDataProtectionBuilder"/> that should use the specified service.</param> | |||||
/// <param name="descriptor">The <see cref="ServiceDescriptor"/> with the service the <paramref name="builder" /> should use.</param> | |||||
/// <returns> | |||||
/// The <paramref name="builder" /> for continued configuration. | |||||
/// </returns> | |||||
/// <exception cref="System.ArgumentNullException"> | |||||
/// Thrown if <paramref name="builder" /> or <paramref name="descriptor" /> is <see langword="null" />. | |||||
/// </exception> | |||||
public static IDataProtectionBuilder Use(this IDataProtectionBuilder builder, ServiceDescriptor descriptor) | |||||
{ | |||||
// This algorithm of removing all other services of a specific type | |||||
// before adding the new/replacement service is how the base ASP.NET | |||||
// DataProtection bits work. Due to some of the differences in how | |||||
// that base set of bits handles DI, it's better to follow suit | |||||
// and work in the same way than to try and debug weird issues. | |||||
if (builder == null) | |||||
{ | |||||
throw new ArgumentNullException(nameof(builder)); | |||||
} | |||||
if (descriptor == null) | |||||
{ | |||||
throw new ArgumentNullException(nameof(descriptor)); | |||||
} | |||||
for (int i = builder.Services.Count - 1; i >= 0; i--) | |||||
{ | |||||
if (builder.Services[i]?.ServiceType == descriptor.ServiceType) | |||||
{ | |||||
builder.Services.RemoveAt(i); | |||||
} | |||||
} | |||||
builder.Services.Add(descriptor); | |||||
return builder; | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,214 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Diagnostics.CodeAnalysis; | |||||
using System.IO; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Text.RegularExpressions; | |||||
using System.Xml.Linq; | |||||
using Microsoft.AspNetCore.DataProtection.Repositories; | |||||
using Microsoft.Extensions.Logging; | |||||
using StackExchange.Redis; | |||||
namespace DataProtectionExtensions | |||||
{ | |||||
/// <summary> | |||||
/// Key repository that stores XML encrypted keys in a Redis distributed cache. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <para> | |||||
/// The values stored in Redis are XML documents that contain encrypted session | |||||
/// keys used for the protection of things like session state. The document contents | |||||
/// are double-encrypted - first with a changing session key; then by a master key. | |||||
/// As such, there's no risk in storing the keys in Redis - even if someone can crack | |||||
/// the master key, they still need to also crack the session key. (Other solutions | |||||
/// for sharing keys across a farm environment include writing them to files | |||||
/// on a file share.) | |||||
/// </para> | |||||
/// <para> | |||||
/// While the repository uses a hash to keep the set of encrypted keys separate, you | |||||
/// can further separate these items from other items in Redis by specifying a unique | |||||
/// database in the connection string. | |||||
/// </para> | |||||
/// <para> | |||||
/// Consumers of the repository are responsible for caching the XML items as needed. | |||||
/// Typically repositories are consumed by things like <see cref="Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingProvider"/> | |||||
/// which generates <see cref="Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.CacheableKeyRing"/> | |||||
/// values that get cached. The mechanism is already optimized for caching so there's | |||||
/// no need to create a redundant cache. | |||||
/// </para> | |||||
/// </remarks> | |||||
/// <seealso cref="Microsoft.AspNetCore.DataProtection.Repositories.IXmlRepository" /> | |||||
/// <seealso cref="System.IDisposable" /> | |||||
public class RedisXmlRepository : IXmlRepository, IDisposable | |||||
{ | |||||
/// <summary> | |||||
/// The root cache key for XML items stored in Redis | |||||
/// </summary> | |||||
public static readonly string RedisHashKey = "DataProtectionXmlRepository"; | |||||
/// <summary> | |||||
/// The connection to the Redis backing store. | |||||
/// </summary> | |||||
private IConnectionMultiplexer _connection; | |||||
/// <summary> | |||||
/// Flag indicating whether the object has been disposed. | |||||
/// </summary> | |||||
private bool _disposed = false; | |||||
/// <summary> | |||||
/// Initializes a new instance of the <see cref="RedisXmlRepository"/> class. | |||||
/// </summary> | |||||
/// <param name="connectionString"> | |||||
/// The Redis connection string. | |||||
/// </param> | |||||
/// <param name="logger"> | |||||
/// The <see cref="ILogger{T}"/> used to log diagnostic messages. | |||||
/// </param> | |||||
/// <exception cref="System.ArgumentNullException"> | |||||
/// Thrown if <paramref name="connectionString" /> or <paramref name="logger" /> is <see langword="null" />. | |||||
/// </exception> | |||||
public RedisXmlRepository(string connectionString, ILogger<RedisXmlRepository> logger) | |||||
: this(ConnectionMultiplexer.Connect(connectionString), logger) | |||||
{ | |||||
} | |||||
/// <summary> | |||||
/// Initializes a new instance of the <see cref="RedisXmlRepository"/> class. | |||||
/// </summary> | |||||
/// <param name="connection"> | |||||
/// The Redis database connection. | |||||
/// </param> | |||||
/// <param name="logger"> | |||||
/// The <see cref="ILogger{T}"/> used to log diagnostic messages. | |||||
/// </param> | |||||
/// <exception cref="System.ArgumentNullException"> | |||||
/// Thrown if <paramref name="connection" /> or <paramref name="logger" /> is <see langword="null" />. | |||||
/// </exception> | |||||
public RedisXmlRepository(IConnectionMultiplexer connection, ILogger<RedisXmlRepository> logger) | |||||
{ | |||||
if (connection == null) | |||||
{ | |||||
throw new ArgumentNullException(nameof(connection)); | |||||
} | |||||
if (logger == null) | |||||
{ | |||||
throw new ArgumentNullException(nameof(logger)); | |||||
} | |||||
this._connection = connection; | |||||
this.Logger = logger; | |||||
// Mask the password so it doesn't get logged. | |||||
var configuration = Regex.Replace(this._connection.Configuration, @"password\s*=\s*[^,]*", "password=****", RegexOptions.IgnoreCase); | |||||
this.Logger.LogDebug("Storing data protection keys in Redis: {RedisConfiguration}", configuration); | |||||
} | |||||
/// <summary> | |||||
/// Gets the logger. | |||||
/// </summary> | |||||
/// <value> | |||||
/// The <see cref="ILogger{T}"/> used to log diagnostic messages. | |||||
/// </value> | |||||
public ILogger<RedisXmlRepository> Logger { get; private set; } | |||||
/// <summary> | |||||
/// Performs application-defined tasks associated with freeing, releasing, | |||||
/// or resetting unmanaged resources. | |||||
/// </summary> | |||||
public void Dispose() | |||||
{ | |||||
this.Dispose(true); | |||||
} | |||||
/// <summary> | |||||
/// Gets all top-level XML elements in the repository. | |||||
/// </summary> | |||||
/// <returns> | |||||
/// An <see cref="IReadOnlyCollection{T}"/> with the set of elements | |||||
/// stored in the repository. | |||||
/// </returns> | |||||
public IReadOnlyCollection<XElement> GetAllElements() | |||||
{ | |||||
var database = this._connection.GetDatabase(); | |||||
var hash = database.HashGetAll(RedisHashKey); | |||||
var elements = new List<XElement>(); | |||||
if (hash == null || hash.Length == 0) | |||||
{ | |||||
return elements.AsReadOnly(); | |||||
} | |||||
foreach (var item in hash.ToStringDictionary()) | |||||
{ | |||||
elements.Add(XElement.Parse(item.Value)); | |||||
} | |||||
this.Logger.LogDebug("Read {XmlElementCount} XML elements from Redis.", elements.Count); | |||||
return elements.AsReadOnly(); | |||||
} | |||||
/// <summary> | |||||
/// Adds a top-level XML element to the repository. | |||||
/// </summary> | |||||
/// <param name="element">The element to add.</param> | |||||
/// <param name="friendlyName"> | |||||
/// An optional name to be associated with the XML element. | |||||
/// For instance, if this repository stores XML files on disk, the friendly name may | |||||
/// be used as part of the file name. Repository implementations are not required to | |||||
/// observe this parameter even if it has been provided by the caller. | |||||
/// </param> | |||||
/// <remarks> | |||||
/// The <paramref name="friendlyName" /> parameter must be unique if specified. | |||||
/// For instance, it could be the ID of the key being stored. | |||||
/// </remarks> | |||||
/// <exception cref="System.ArgumentNullException"> | |||||
/// Thrown if <paramref name="element" /> is <see langword="null" />. | |||||
/// </exception> | |||||
public void StoreElement(XElement element, string friendlyName) | |||||
{ | |||||
if (element == null) | |||||
{ | |||||
throw new ArgumentNullException(nameof(element)); | |||||
} | |||||
if (string.IsNullOrEmpty(friendlyName)) | |||||
{ | |||||
// The framework always passes in a name, but | |||||
// the contract indicates this may be null or empty. | |||||
friendlyName = Guid.NewGuid().ToString(); | |||||
} | |||||
this.Logger.LogDebug("Storing XML element with friendly name {XmlElementFriendlyName}.", friendlyName); | |||||
this._connection.GetDatabase().HashSet(RedisHashKey, friendlyName, element.ToString()); | |||||
} | |||||
/// <summary> | |||||
/// Releases unmanaged and - optionally - managed resources. | |||||
/// </summary> | |||||
/// <param name="disposing"> | |||||
/// <see langword="true" /> to release both managed and unmanaged resources; | |||||
/// <see langword="false" /> to release only unmanaged resources. | |||||
/// </param> | |||||
protected virtual void Dispose(bool disposing) | |||||
{ | |||||
if (!this._disposed) | |||||
{ | |||||
if (disposing) | |||||
{ | |||||
if (this._connection != null) | |||||
{ | |||||
this._connection.Close(); | |||||
this._connection.Dispose(); | |||||
} | |||||
} | |||||
this._connection = null; | |||||
this._disposed = true; | |||||
} | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,52 @@ | |||||
using System; | |||||
using Microsoft.EntityFrameworkCore; | |||||
using Microsoft.EntityFrameworkCore.Infrastructure; | |||||
using Microsoft.EntityFrameworkCore.Metadata; | |||||
using Microsoft.EntityFrameworkCore.Migrations; | |||||
using IdentityServer4.EntityFramework.DbContexts; | |||||
namespace Identity.API.Migrations | |||||
{ | |||||
[DbContext(typeof(PersistedGrantDbContext))] | |||||
[Migration("20170604151240_Init-persisted-grant")] | |||||
partial class Initpersistedgrant | |||||
{ | |||||
protected override void BuildTargetModel(ModelBuilder modelBuilder) | |||||
{ | |||||
modelBuilder | |||||
.HasAnnotation("ProductVersion", "1.1.2") | |||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.PersistedGrant", b => | |||||
{ | |||||
b.Property<string>("Key") | |||||
.HasMaxLength(200); | |||||
b.Property<string>("ClientId") | |||||
.IsRequired() | |||||
.HasMaxLength(200); | |||||
b.Property<DateTime>("CreationTime"); | |||||
b.Property<string>("Data") | |||||
.IsRequired() | |||||
.HasMaxLength(50000); | |||||
b.Property<DateTime?>("Expiration"); | |||||
b.Property<string>("SubjectId") | |||||
.HasMaxLength(200); | |||||
b.Property<string>("Type") | |||||
.IsRequired() | |||||
.HasMaxLength(50); | |||||
b.HasKey("Key"); | |||||
b.HasIndex("SubjectId", "ClientId", "Type"); | |||||
b.ToTable("PersistedGrants"); | |||||
}); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,40 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using Microsoft.EntityFrameworkCore.Migrations; | |||||
namespace Identity.API.Migrations | |||||
{ | |||||
public partial class Initpersistedgrant : Migration | |||||
{ | |||||
protected override void Up(MigrationBuilder migrationBuilder) | |||||
{ | |||||
migrationBuilder.CreateTable( | |||||
name: "PersistedGrants", | |||||
columns: table => new | |||||
{ | |||||
Key = table.Column<string>(maxLength: 200, nullable: false), | |||||
ClientId = table.Column<string>(maxLength: 200, nullable: false), | |||||
CreationTime = table.Column<DateTime>(nullable: false), | |||||
Data = table.Column<string>(maxLength: 50000, nullable: false), | |||||
Expiration = table.Column<DateTime>(nullable: true), | |||||
SubjectId = table.Column<string>(maxLength: 200, nullable: true), | |||||
Type = table.Column<string>(maxLength: 50, nullable: false) | |||||
}, | |||||
constraints: table => | |||||
{ | |||||
table.PrimaryKey("PK_PersistedGrants", x => x.Key); | |||||
}); | |||||
migrationBuilder.CreateIndex( | |||||
name: "IX_PersistedGrants_SubjectId_ClientId_Type", | |||||
table: "PersistedGrants", | |||||
columns: new[] { "SubjectId", "ClientId", "Type" }); | |||||
} | |||||
protected override void Down(MigrationBuilder migrationBuilder) | |||||
{ | |||||
migrationBuilder.DropTable( | |||||
name: "PersistedGrants"); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,539 @@ | |||||
using System; | |||||
using Microsoft.EntityFrameworkCore; | |||||
using Microsoft.EntityFrameworkCore.Infrastructure; | |||||
using Microsoft.EntityFrameworkCore.Metadata; | |||||
using Microsoft.EntityFrameworkCore.Migrations; | |||||
using IdentityServer4.EntityFramework.DbContexts; | |||||
namespace Identity.API.Migrations.ConfigurationDb | |||||
{ | |||||
[DbContext(typeof(ConfigurationDbContext))] | |||||
[Migration("20170604151338_Init-configuration")] | |||||
partial class Initconfiguration | |||||
{ | |||||
protected override void BuildTargetModel(ModelBuilder modelBuilder) | |||||
{ | |||||
modelBuilder | |||||
.HasAnnotation("ProductVersion", "1.1.2") | |||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResource", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<string>("Description") | |||||
.HasMaxLength(1000); | |||||
b.Property<string>("DisplayName") | |||||
.HasMaxLength(200); | |||||
b.Property<bool>("Enabled"); | |||||
b.Property<string>("Name") | |||||
.IsRequired() | |||||
.HasMaxLength(200); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("Name") | |||||
.IsUnique(); | |||||
b.ToTable("ApiResources"); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceClaim", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<int?>("ApiResourceId") | |||||
.IsRequired(); | |||||
b.Property<string>("Type") | |||||
.IsRequired() | |||||
.HasMaxLength(200); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("ApiResourceId"); | |||||
b.ToTable("ApiClaims"); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScope", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<int?>("ApiResourceId") | |||||
.IsRequired(); | |||||
b.Property<string>("Description") | |||||
.HasMaxLength(1000); | |||||
b.Property<string>("DisplayName") | |||||
.HasMaxLength(200); | |||||
b.Property<bool>("Emphasize"); | |||||
b.Property<string>("Name") | |||||
.IsRequired() | |||||
.HasMaxLength(200); | |||||
b.Property<bool>("Required"); | |||||
b.Property<bool>("ShowInDiscoveryDocument"); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("ApiResourceId"); | |||||
b.HasIndex("Name") | |||||
.IsUnique(); | |||||
b.ToTable("ApiScopes"); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScopeClaim", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<int?>("ApiScopeId") | |||||
.IsRequired(); | |||||
b.Property<string>("Type") | |||||
.IsRequired() | |||||
.HasMaxLength(200); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("ApiScopeId"); | |||||
b.ToTable("ApiScopeClaims"); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiSecret", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<int?>("ApiResourceId") | |||||
.IsRequired(); | |||||
b.Property<string>("Description") | |||||
.HasMaxLength(1000); | |||||
b.Property<DateTime?>("Expiration"); | |||||
b.Property<string>("Type") | |||||
.HasMaxLength(250); | |||||
b.Property<string>("Value") | |||||
.HasMaxLength(2000); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("ApiResourceId"); | |||||
b.ToTable("ApiSecrets"); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.Client", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<int>("AbsoluteRefreshTokenLifetime"); | |||||
b.Property<int>("AccessTokenLifetime"); | |||||
b.Property<int>("AccessTokenType"); | |||||
b.Property<bool>("AllowAccessTokensViaBrowser"); | |||||
b.Property<bool>("AllowOfflineAccess"); | |||||
b.Property<bool>("AllowPlainTextPkce"); | |||||
b.Property<bool>("AllowRememberConsent"); | |||||
b.Property<bool>("AlwaysIncludeUserClaimsInIdToken"); | |||||
b.Property<bool>("AlwaysSendClientClaims"); | |||||
b.Property<int>("AuthorizationCodeLifetime"); | |||||
b.Property<string>("ClientId") | |||||
.IsRequired() | |||||
.HasMaxLength(200); | |||||
b.Property<string>("ClientName") | |||||
.HasMaxLength(200); | |||||
b.Property<string>("ClientUri") | |||||
.HasMaxLength(2000); | |||||
b.Property<bool>("EnableLocalLogin"); | |||||
b.Property<bool>("Enabled"); | |||||
b.Property<int>("IdentityTokenLifetime"); | |||||
b.Property<bool>("IncludeJwtId"); | |||||
b.Property<string>("LogoUri"); | |||||
b.Property<bool>("LogoutSessionRequired"); | |||||
b.Property<string>("LogoutUri"); | |||||
b.Property<bool>("PrefixClientClaims"); | |||||
b.Property<string>("ProtocolType") | |||||
.IsRequired() | |||||
.HasMaxLength(200); | |||||
b.Property<int>("RefreshTokenExpiration"); | |||||
b.Property<int>("RefreshTokenUsage"); | |||||
b.Property<bool>("RequireClientSecret"); | |||||
b.Property<bool>("RequireConsent"); | |||||
b.Property<bool>("RequirePkce"); | |||||
b.Property<int>("SlidingRefreshTokenLifetime"); | |||||
b.Property<bool>("UpdateAccessTokenClaimsOnRefresh"); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("ClientId") | |||||
.IsUnique(); | |||||
b.ToTable("Clients"); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientClaim", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<int?>("ClientId") | |||||
.IsRequired(); | |||||
b.Property<string>("Type") | |||||
.IsRequired() | |||||
.HasMaxLength(250); | |||||
b.Property<string>("Value") | |||||
.IsRequired() | |||||
.HasMaxLength(250); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("ClientId"); | |||||
b.ToTable("ClientClaims"); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientCorsOrigin", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<int?>("ClientId") | |||||
.IsRequired(); | |||||
b.Property<string>("Origin") | |||||
.IsRequired() | |||||
.HasMaxLength(150); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("ClientId"); | |||||
b.ToTable("ClientCorsOrigins"); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientGrantType", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<int?>("ClientId") | |||||
.IsRequired(); | |||||
b.Property<string>("GrantType") | |||||
.IsRequired() | |||||
.HasMaxLength(250); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("ClientId"); | |||||
b.ToTable("ClientGrantTypes"); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientIdPRestriction", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<int?>("ClientId") | |||||
.IsRequired(); | |||||
b.Property<string>("Provider") | |||||
.IsRequired() | |||||
.HasMaxLength(200); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("ClientId"); | |||||
b.ToTable("ClientIdPRestrictions"); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientPostLogoutRedirectUri", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<int?>("ClientId") | |||||
.IsRequired(); | |||||
b.Property<string>("PostLogoutRedirectUri") | |||||
.IsRequired() | |||||
.HasMaxLength(2000); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("ClientId"); | |||||
b.ToTable("ClientPostLogoutRedirectUris"); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientRedirectUri", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<int?>("ClientId") | |||||
.IsRequired(); | |||||
b.Property<string>("RedirectUri") | |||||
.IsRequired() | |||||
.HasMaxLength(2000); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("ClientId"); | |||||
b.ToTable("ClientRedirectUris"); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientScope", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<int?>("ClientId") | |||||
.IsRequired(); | |||||
b.Property<string>("Scope") | |||||
.IsRequired() | |||||
.HasMaxLength(200); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("ClientId"); | |||||
b.ToTable("ClientScopes"); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientSecret", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<int?>("ClientId") | |||||
.IsRequired(); | |||||
b.Property<string>("Description") | |||||
.HasMaxLength(2000); | |||||
b.Property<DateTime?>("Expiration"); | |||||
b.Property<string>("Type") | |||||
.HasMaxLength(250); | |||||
b.Property<string>("Value") | |||||
.IsRequired() | |||||
.HasMaxLength(2000); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("ClientId"); | |||||
b.ToTable("ClientSecrets"); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityClaim", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<int?>("IdentityResourceId") | |||||
.IsRequired(); | |||||
b.Property<string>("Type") | |||||
.IsRequired() | |||||
.HasMaxLength(200); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("IdentityResourceId"); | |||||
b.ToTable("IdentityClaims"); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityResource", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<string>("Description") | |||||
.HasMaxLength(1000); | |||||
b.Property<string>("DisplayName") | |||||
.HasMaxLength(200); | |||||
b.Property<bool>("Emphasize"); | |||||
b.Property<bool>("Enabled"); | |||||
b.Property<string>("Name") | |||||
.IsRequired() | |||||
.HasMaxLength(200); | |||||
b.Property<bool>("Required"); | |||||
b.Property<bool>("ShowInDiscoveryDocument"); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("Name") | |||||
.IsUnique(); | |||||
b.ToTable("IdentityResources"); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceClaim", b => | |||||
{ | |||||
b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource") | |||||
.WithMany("UserClaims") | |||||
.HasForeignKey("ApiResourceId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScope", b => | |||||
{ | |||||
b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource") | |||||
.WithMany("Scopes") | |||||
.HasForeignKey("ApiResourceId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScopeClaim", b => | |||||
{ | |||||
b.HasOne("IdentityServer4.EntityFramework.Entities.ApiScope", "ApiScope") | |||||
.WithMany("UserClaims") | |||||
.HasForeignKey("ApiScopeId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiSecret", b => | |||||
{ | |||||
b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource") | |||||
.WithMany("Secrets") | |||||
.HasForeignKey("ApiResourceId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientClaim", b => | |||||
{ | |||||
b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") | |||||
.WithMany("Claims") | |||||
.HasForeignKey("ClientId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientCorsOrigin", b => | |||||
{ | |||||
b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") | |||||
.WithMany("AllowedCorsOrigins") | |||||
.HasForeignKey("ClientId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientGrantType", b => | |||||
{ | |||||
b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") | |||||
.WithMany("AllowedGrantTypes") | |||||
.HasForeignKey("ClientId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientIdPRestriction", b => | |||||
{ | |||||
b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") | |||||
.WithMany("IdentityProviderRestrictions") | |||||
.HasForeignKey("ClientId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientPostLogoutRedirectUri", b => | |||||
{ | |||||
b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") | |||||
.WithMany("PostLogoutRedirectUris") | |||||
.HasForeignKey("ClientId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientRedirectUri", b => | |||||
{ | |||||
b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") | |||||
.WithMany("RedirectUris") | |||||
.HasForeignKey("ClientId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientScope", b => | |||||
{ | |||||
b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") | |||||
.WithMany("AllowedScopes") | |||||
.HasForeignKey("ClientId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientSecret", b => | |||||
{ | |||||
b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") | |||||
.WithMany("ClientSecrets") | |||||
.HasForeignKey("ClientId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityClaim", b => | |||||
{ | |||||
b.HasOne("IdentityServer4.EntityFramework.Entities.IdentityResource", "IdentityResource") | |||||
.WithMany("UserClaims") | |||||
.HasForeignKey("IdentityResourceId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
}); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,501 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using Microsoft.EntityFrameworkCore.Migrations; | |||||
using Microsoft.EntityFrameworkCore.Metadata; | |||||
namespace Identity.API.Migrations.ConfigurationDb | |||||
{ | |||||
public partial class Initconfiguration : Migration | |||||
{ | |||||
protected override void Up(MigrationBuilder migrationBuilder) | |||||
{ | |||||
migrationBuilder.CreateTable( | |||||
name: "ApiResources", | |||||
columns: table => new | |||||
{ | |||||
Id = table.Column<int>(nullable: false) | |||||
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), | |||||
Description = table.Column<string>(maxLength: 1000, nullable: true), | |||||
DisplayName = table.Column<string>(maxLength: 200, nullable: true), | |||||
Enabled = table.Column<bool>(nullable: false), | |||||
Name = table.Column<string>(maxLength: 200, nullable: false) | |||||
}, | |||||
constraints: table => | |||||
{ | |||||
table.PrimaryKey("PK_ApiResources", x => x.Id); | |||||
}); | |||||
migrationBuilder.CreateTable( | |||||
name: "Clients", | |||||
columns: table => new | |||||
{ | |||||
Id = table.Column<int>(nullable: false) | |||||
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), | |||||
AbsoluteRefreshTokenLifetime = table.Column<int>(nullable: false), | |||||
AccessTokenLifetime = table.Column<int>(nullable: false), | |||||
AccessTokenType = table.Column<int>(nullable: false), | |||||
AllowAccessTokensViaBrowser = table.Column<bool>(nullable: false), | |||||
AllowOfflineAccess = table.Column<bool>(nullable: false), | |||||
AllowPlainTextPkce = table.Column<bool>(nullable: false), | |||||
AllowRememberConsent = table.Column<bool>(nullable: false), | |||||
AlwaysIncludeUserClaimsInIdToken = table.Column<bool>(nullable: false), | |||||
AlwaysSendClientClaims = table.Column<bool>(nullable: false), | |||||
AuthorizationCodeLifetime = table.Column<int>(nullable: false), | |||||
ClientId = table.Column<string>(maxLength: 200, nullable: false), | |||||
ClientName = table.Column<string>(maxLength: 200, nullable: true), | |||||
ClientUri = table.Column<string>(maxLength: 2000, nullable: true), | |||||
EnableLocalLogin = table.Column<bool>(nullable: false), | |||||
Enabled = table.Column<bool>(nullable: false), | |||||
IdentityTokenLifetime = table.Column<int>(nullable: false), | |||||
IncludeJwtId = table.Column<bool>(nullable: false), | |||||
LogoUri = table.Column<string>(nullable: true), | |||||
LogoutSessionRequired = table.Column<bool>(nullable: false), | |||||
LogoutUri = table.Column<string>(nullable: true), | |||||
PrefixClientClaims = table.Column<bool>(nullable: false), | |||||
ProtocolType = table.Column<string>(maxLength: 200, nullable: false), | |||||
RefreshTokenExpiration = table.Column<int>(nullable: false), | |||||
RefreshTokenUsage = table.Column<int>(nullable: false), | |||||
RequireClientSecret = table.Column<bool>(nullable: false), | |||||
RequireConsent = table.Column<bool>(nullable: false), | |||||
RequirePkce = table.Column<bool>(nullable: false), | |||||
SlidingRefreshTokenLifetime = table.Column<int>(nullable: false), | |||||
UpdateAccessTokenClaimsOnRefresh = table.Column<bool>(nullable: false) | |||||
}, | |||||
constraints: table => | |||||
{ | |||||
table.PrimaryKey("PK_Clients", x => x.Id); | |||||
}); | |||||
migrationBuilder.CreateTable( | |||||
name: "IdentityResources", | |||||
columns: table => new | |||||
{ | |||||
Id = table.Column<int>(nullable: false) | |||||
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), | |||||
Description = table.Column<string>(maxLength: 1000, nullable: true), | |||||
DisplayName = table.Column<string>(maxLength: 200, nullable: true), | |||||
Emphasize = table.Column<bool>(nullable: false), | |||||
Enabled = table.Column<bool>(nullable: false), | |||||
Name = table.Column<string>(maxLength: 200, nullable: false), | |||||
Required = table.Column<bool>(nullable: false), | |||||
ShowInDiscoveryDocument = table.Column<bool>(nullable: false) | |||||
}, | |||||
constraints: table => | |||||
{ | |||||
table.PrimaryKey("PK_IdentityResources", x => x.Id); | |||||
}); | |||||
migrationBuilder.CreateTable( | |||||
name: "ApiClaims", | |||||
columns: table => new | |||||
{ | |||||
Id = table.Column<int>(nullable: false) | |||||
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), | |||||
ApiResourceId = table.Column<int>(nullable: false), | |||||
Type = table.Column<string>(maxLength: 200, nullable: false) | |||||
}, | |||||
constraints: table => | |||||
{ | |||||
table.PrimaryKey("PK_ApiClaims", x => x.Id); | |||||
table.ForeignKey( | |||||
name: "FK_ApiClaims_ApiResources_ApiResourceId", | |||||
column: x => x.ApiResourceId, | |||||
principalTable: "ApiResources", | |||||
principalColumn: "Id", | |||||
onDelete: ReferentialAction.Cascade); | |||||
}); | |||||
migrationBuilder.CreateTable( | |||||
name: "ApiScopes", | |||||
columns: table => new | |||||
{ | |||||
Id = table.Column<int>(nullable: false) | |||||
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), | |||||
ApiResourceId = table.Column<int>(nullable: false), | |||||
Description = table.Column<string>(maxLength: 1000, nullable: true), | |||||
DisplayName = table.Column<string>(maxLength: 200, nullable: true), | |||||
Emphasize = table.Column<bool>(nullable: false), | |||||
Name = table.Column<string>(maxLength: 200, nullable: false), | |||||
Required = table.Column<bool>(nullable: false), | |||||
ShowInDiscoveryDocument = table.Column<bool>(nullable: false) | |||||
}, | |||||
constraints: table => | |||||
{ | |||||
table.PrimaryKey("PK_ApiScopes", x => x.Id); | |||||
table.ForeignKey( | |||||
name: "FK_ApiScopes_ApiResources_ApiResourceId", | |||||
column: x => x.ApiResourceId, | |||||
principalTable: "ApiResources", | |||||
principalColumn: "Id", | |||||
onDelete: ReferentialAction.Cascade); | |||||
}); | |||||
migrationBuilder.CreateTable( | |||||
name: "ApiSecrets", | |||||
columns: table => new | |||||
{ | |||||
Id = table.Column<int>(nullable: false) | |||||
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), | |||||
ApiResourceId = table.Column<int>(nullable: false), | |||||
Description = table.Column<string>(maxLength: 1000, nullable: true), | |||||
Expiration = table.Column<DateTime>(nullable: true), | |||||
Type = table.Column<string>(maxLength: 250, nullable: true), | |||||
Value = table.Column<string>(maxLength: 2000, nullable: true) | |||||
}, | |||||
constraints: table => | |||||
{ | |||||
table.PrimaryKey("PK_ApiSecrets", x => x.Id); | |||||
table.ForeignKey( | |||||
name: "FK_ApiSecrets_ApiResources_ApiResourceId", | |||||
column: x => x.ApiResourceId, | |||||
principalTable: "ApiResources", | |||||
principalColumn: "Id", | |||||
onDelete: ReferentialAction.Cascade); | |||||
}); | |||||
migrationBuilder.CreateTable( | |||||
name: "ClientClaims", | |||||
columns: table => new | |||||
{ | |||||
Id = table.Column<int>(nullable: false) | |||||
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), | |||||
ClientId = table.Column<int>(nullable: false), | |||||
Type = table.Column<string>(maxLength: 250, nullable: false), | |||||
Value = table.Column<string>(maxLength: 250, nullable: false) | |||||
}, | |||||
constraints: table => | |||||
{ | |||||
table.PrimaryKey("PK_ClientClaims", x => x.Id); | |||||
table.ForeignKey( | |||||
name: "FK_ClientClaims_Clients_ClientId", | |||||
column: x => x.ClientId, | |||||
principalTable: "Clients", | |||||
principalColumn: "Id", | |||||
onDelete: ReferentialAction.Cascade); | |||||
}); | |||||
migrationBuilder.CreateTable( | |||||
name: "ClientCorsOrigins", | |||||
columns: table => new | |||||
{ | |||||
Id = table.Column<int>(nullable: false) | |||||
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), | |||||
ClientId = table.Column<int>(nullable: false), | |||||
Origin = table.Column<string>(maxLength: 150, nullable: false) | |||||
}, | |||||
constraints: table => | |||||
{ | |||||
table.PrimaryKey("PK_ClientCorsOrigins", x => x.Id); | |||||
table.ForeignKey( | |||||
name: "FK_ClientCorsOrigins_Clients_ClientId", | |||||
column: x => x.ClientId, | |||||
principalTable: "Clients", | |||||
principalColumn: "Id", | |||||
onDelete: ReferentialAction.Cascade); | |||||
}); | |||||
migrationBuilder.CreateTable( | |||||
name: "ClientGrantTypes", | |||||
columns: table => new | |||||
{ | |||||
Id = table.Column<int>(nullable: false) | |||||
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), | |||||
ClientId = table.Column<int>(nullable: false), | |||||
GrantType = table.Column<string>(maxLength: 250, nullable: false) | |||||
}, | |||||
constraints: table => | |||||
{ | |||||
table.PrimaryKey("PK_ClientGrantTypes", x => x.Id); | |||||
table.ForeignKey( | |||||
name: "FK_ClientGrantTypes_Clients_ClientId", | |||||
column: x => x.ClientId, | |||||
principalTable: "Clients", | |||||
principalColumn: "Id", | |||||
onDelete: ReferentialAction.Cascade); | |||||
}); | |||||
migrationBuilder.CreateTable( | |||||
name: "ClientIdPRestrictions", | |||||
columns: table => new | |||||
{ | |||||
Id = table.Column<int>(nullable: false) | |||||
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), | |||||
ClientId = table.Column<int>(nullable: false), | |||||
Provider = table.Column<string>(maxLength: 200, nullable: false) | |||||
}, | |||||
constraints: table => | |||||
{ | |||||
table.PrimaryKey("PK_ClientIdPRestrictions", x => x.Id); | |||||
table.ForeignKey( | |||||
name: "FK_ClientIdPRestrictions_Clients_ClientId", | |||||
column: x => x.ClientId, | |||||
principalTable: "Clients", | |||||
principalColumn: "Id", | |||||
onDelete: ReferentialAction.Cascade); | |||||
}); | |||||
migrationBuilder.CreateTable( | |||||
name: "ClientPostLogoutRedirectUris", | |||||
columns: table => new | |||||
{ | |||||
Id = table.Column<int>(nullable: false) | |||||
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), | |||||
ClientId = table.Column<int>(nullable: false), | |||||
PostLogoutRedirectUri = table.Column<string>(maxLength: 2000, nullable: false) | |||||
}, | |||||
constraints: table => | |||||
{ | |||||
table.PrimaryKey("PK_ClientPostLogoutRedirectUris", x => x.Id); | |||||
table.ForeignKey( | |||||
name: "FK_ClientPostLogoutRedirectUris_Clients_ClientId", | |||||
column: x => x.ClientId, | |||||
principalTable: "Clients", | |||||
principalColumn: "Id", | |||||
onDelete: ReferentialAction.Cascade); | |||||
}); | |||||
migrationBuilder.CreateTable( | |||||
name: "ClientRedirectUris", | |||||
columns: table => new | |||||
{ | |||||
Id = table.Column<int>(nullable: false) | |||||
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), | |||||
ClientId = table.Column<int>(nullable: false), | |||||
RedirectUri = table.Column<string>(maxLength: 2000, nullable: false) | |||||
}, | |||||
constraints: table => | |||||
{ | |||||
table.PrimaryKey("PK_ClientRedirectUris", x => x.Id); | |||||
table.ForeignKey( | |||||
name: "FK_ClientRedirectUris_Clients_ClientId", | |||||
column: x => x.ClientId, | |||||
principalTable: "Clients", | |||||
principalColumn: "Id", | |||||
onDelete: ReferentialAction.Cascade); | |||||
}); | |||||
migrationBuilder.CreateTable( | |||||
name: "ClientScopes", | |||||
columns: table => new | |||||
{ | |||||
Id = table.Column<int>(nullable: false) | |||||
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), | |||||
ClientId = table.Column<int>(nullable: false), | |||||
Scope = table.Column<string>(maxLength: 200, nullable: false) | |||||
}, | |||||
constraints: table => | |||||
{ | |||||
table.PrimaryKey("PK_ClientScopes", x => x.Id); | |||||
table.ForeignKey( | |||||
name: "FK_ClientScopes_Clients_ClientId", | |||||
column: x => x.ClientId, | |||||
principalTable: "Clients", | |||||
principalColumn: "Id", | |||||
onDelete: ReferentialAction.Cascade); | |||||
}); | |||||
migrationBuilder.CreateTable( | |||||
name: "ClientSecrets", | |||||
columns: table => new | |||||
{ | |||||
Id = table.Column<int>(nullable: false) | |||||
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), | |||||
ClientId = table.Column<int>(nullable: false), | |||||
Description = table.Column<string>(maxLength: 2000, nullable: true), | |||||
Expiration = table.Column<DateTime>(nullable: true), | |||||
Type = table.Column<string>(maxLength: 250, nullable: true), | |||||
Value = table.Column<string>(maxLength: 2000, nullable: false) | |||||
}, | |||||
constraints: table => | |||||
{ | |||||
table.PrimaryKey("PK_ClientSecrets", x => x.Id); | |||||
table.ForeignKey( | |||||
name: "FK_ClientSecrets_Clients_ClientId", | |||||
column: x => x.ClientId, | |||||
principalTable: "Clients", | |||||
principalColumn: "Id", | |||||
onDelete: ReferentialAction.Cascade); | |||||
}); | |||||
migrationBuilder.CreateTable( | |||||
name: "IdentityClaims", | |||||
columns: table => new | |||||
{ | |||||
Id = table.Column<int>(nullable: false) | |||||
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), | |||||
IdentityResourceId = table.Column<int>(nullable: false), | |||||
Type = table.Column<string>(maxLength: 200, nullable: false) | |||||
}, | |||||
constraints: table => | |||||
{ | |||||
table.PrimaryKey("PK_IdentityClaims", x => x.Id); | |||||
table.ForeignKey( | |||||
name: "FK_IdentityClaims_IdentityResources_IdentityResourceId", | |||||
column: x => x.IdentityResourceId, | |||||
principalTable: "IdentityResources", | |||||
principalColumn: "Id", | |||||
onDelete: ReferentialAction.Cascade); | |||||
}); | |||||
migrationBuilder.CreateTable( | |||||
name: "ApiScopeClaims", | |||||
columns: table => new | |||||
{ | |||||
Id = table.Column<int>(nullable: false) | |||||
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), | |||||
ApiScopeId = table.Column<int>(nullable: false), | |||||
Type = table.Column<string>(maxLength: 200, nullable: false) | |||||
}, | |||||
constraints: table => | |||||
{ | |||||
table.PrimaryKey("PK_ApiScopeClaims", x => x.Id); | |||||
table.ForeignKey( | |||||
name: "FK_ApiScopeClaims_ApiScopes_ApiScopeId", | |||||
column: x => x.ApiScopeId, | |||||
principalTable: "ApiScopes", | |||||
principalColumn: "Id", | |||||
onDelete: ReferentialAction.Cascade); | |||||
}); | |||||
migrationBuilder.CreateIndex( | |||||
name: "IX_ApiResources_Name", | |||||
table: "ApiResources", | |||||
column: "Name", | |||||
unique: true); | |||||
migrationBuilder.CreateIndex( | |||||
name: "IX_ApiClaims_ApiResourceId", | |||||
table: "ApiClaims", | |||||
column: "ApiResourceId"); | |||||
migrationBuilder.CreateIndex( | |||||
name: "IX_ApiScopes_ApiResourceId", | |||||
table: "ApiScopes", | |||||
column: "ApiResourceId"); | |||||
migrationBuilder.CreateIndex( | |||||
name: "IX_ApiScopes_Name", | |||||
table: "ApiScopes", | |||||
column: "Name", | |||||
unique: true); | |||||
migrationBuilder.CreateIndex( | |||||
name: "IX_ApiScopeClaims_ApiScopeId", | |||||
table: "ApiScopeClaims", | |||||
column: "ApiScopeId"); | |||||
migrationBuilder.CreateIndex( | |||||
name: "IX_ApiSecrets_ApiResourceId", | |||||
table: "ApiSecrets", | |||||
column: "ApiResourceId"); | |||||
migrationBuilder.CreateIndex( | |||||
name: "IX_Clients_ClientId", | |||||
table: "Clients", | |||||
column: "ClientId", | |||||
unique: true); | |||||
migrationBuilder.CreateIndex( | |||||
name: "IX_ClientClaims_ClientId", | |||||
table: "ClientClaims", | |||||
column: "ClientId"); | |||||
migrationBuilder.CreateIndex( | |||||
name: "IX_ClientCorsOrigins_ClientId", | |||||
table: "ClientCorsOrigins", | |||||
column: "ClientId"); | |||||
migrationBuilder.CreateIndex( | |||||
name: "IX_ClientGrantTypes_ClientId", | |||||
table: "ClientGrantTypes", | |||||
column: "ClientId"); | |||||
migrationBuilder.CreateIndex( | |||||
name: "IX_ClientIdPRestrictions_ClientId", | |||||
table: "ClientIdPRestrictions", | |||||
column: "ClientId"); | |||||
migrationBuilder.CreateIndex( | |||||
name: "IX_ClientPostLogoutRedirectUris_ClientId", | |||||
table: "ClientPostLogoutRedirectUris", | |||||
column: "ClientId"); | |||||
migrationBuilder.CreateIndex( | |||||
name: "IX_ClientRedirectUris_ClientId", | |||||
table: "ClientRedirectUris", | |||||
column: "ClientId"); | |||||
migrationBuilder.CreateIndex( | |||||
name: "IX_ClientScopes_ClientId", | |||||
table: "ClientScopes", | |||||
column: "ClientId"); | |||||
migrationBuilder.CreateIndex( | |||||
name: "IX_ClientSecrets_ClientId", | |||||
table: "ClientSecrets", | |||||
column: "ClientId"); | |||||
migrationBuilder.CreateIndex( | |||||
name: "IX_IdentityClaims_IdentityResourceId", | |||||
table: "IdentityClaims", | |||||
column: "IdentityResourceId"); | |||||
migrationBuilder.CreateIndex( | |||||
name: "IX_IdentityResources_Name", | |||||
table: "IdentityResources", | |||||
column: "Name", | |||||
unique: true); | |||||
} | |||||
protected override void Down(MigrationBuilder migrationBuilder) | |||||
{ | |||||
migrationBuilder.DropTable( | |||||
name: "ApiClaims"); | |||||
migrationBuilder.DropTable( | |||||
name: "ApiScopeClaims"); | |||||
migrationBuilder.DropTable( | |||||
name: "ApiSecrets"); | |||||
migrationBuilder.DropTable( | |||||
name: "ClientClaims"); | |||||
migrationBuilder.DropTable( | |||||
name: "ClientCorsOrigins"); | |||||
migrationBuilder.DropTable( | |||||
name: "ClientGrantTypes"); | |||||
migrationBuilder.DropTable( | |||||
name: "ClientIdPRestrictions"); | |||||
migrationBuilder.DropTable( | |||||
name: "ClientPostLogoutRedirectUris"); | |||||
migrationBuilder.DropTable( | |||||
name: "ClientRedirectUris"); | |||||
migrationBuilder.DropTable( | |||||
name: "ClientScopes"); | |||||
migrationBuilder.DropTable( | |||||
name: "ClientSecrets"); | |||||
migrationBuilder.DropTable( | |||||
name: "IdentityClaims"); | |||||
migrationBuilder.DropTable( | |||||
name: "ApiScopes"); | |||||
migrationBuilder.DropTable( | |||||
name: "Clients"); | |||||
migrationBuilder.DropTable( | |||||
name: "IdentityResources"); | |||||
migrationBuilder.DropTable( | |||||
name: "ApiResources"); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,538 @@ | |||||
using System; | |||||
using Microsoft.EntityFrameworkCore; | |||||
using Microsoft.EntityFrameworkCore.Infrastructure; | |||||
using Microsoft.EntityFrameworkCore.Metadata; | |||||
using Microsoft.EntityFrameworkCore.Migrations; | |||||
using IdentityServer4.EntityFramework.DbContexts; | |||||
namespace Identity.API.Migrations.ConfigurationDb | |||||
{ | |||||
[DbContext(typeof(ConfigurationDbContext))] | |||||
partial class ConfigurationDbContextModelSnapshot : ModelSnapshot | |||||
{ | |||||
protected override void BuildModel(ModelBuilder modelBuilder) | |||||
{ | |||||
modelBuilder | |||||
.HasAnnotation("ProductVersion", "1.1.2") | |||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResource", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<string>("Description") | |||||
.HasMaxLength(1000); | |||||
b.Property<string>("DisplayName") | |||||
.HasMaxLength(200); | |||||
b.Property<bool>("Enabled"); | |||||
b.Property<string>("Name") | |||||
.IsRequired() | |||||
.HasMaxLength(200); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("Name") | |||||
.IsUnique(); | |||||
b.ToTable("ApiResources"); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceClaim", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<int?>("ApiResourceId") | |||||
.IsRequired(); | |||||
b.Property<string>("Type") | |||||
.IsRequired() | |||||
.HasMaxLength(200); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("ApiResourceId"); | |||||
b.ToTable("ApiClaims"); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScope", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<int?>("ApiResourceId") | |||||
.IsRequired(); | |||||
b.Property<string>("Description") | |||||
.HasMaxLength(1000); | |||||
b.Property<string>("DisplayName") | |||||
.HasMaxLength(200); | |||||
b.Property<bool>("Emphasize"); | |||||
b.Property<string>("Name") | |||||
.IsRequired() | |||||
.HasMaxLength(200); | |||||
b.Property<bool>("Required"); | |||||
b.Property<bool>("ShowInDiscoveryDocument"); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("ApiResourceId"); | |||||
b.HasIndex("Name") | |||||
.IsUnique(); | |||||
b.ToTable("ApiScopes"); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScopeClaim", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<int?>("ApiScopeId") | |||||
.IsRequired(); | |||||
b.Property<string>("Type") | |||||
.IsRequired() | |||||
.HasMaxLength(200); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("ApiScopeId"); | |||||
b.ToTable("ApiScopeClaims"); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiSecret", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<int?>("ApiResourceId") | |||||
.IsRequired(); | |||||
b.Property<string>("Description") | |||||
.HasMaxLength(1000); | |||||
b.Property<DateTime?>("Expiration"); | |||||
b.Property<string>("Type") | |||||
.HasMaxLength(250); | |||||
b.Property<string>("Value") | |||||
.HasMaxLength(2000); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("ApiResourceId"); | |||||
b.ToTable("ApiSecrets"); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.Client", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<int>("AbsoluteRefreshTokenLifetime"); | |||||
b.Property<int>("AccessTokenLifetime"); | |||||
b.Property<int>("AccessTokenType"); | |||||
b.Property<bool>("AllowAccessTokensViaBrowser"); | |||||
b.Property<bool>("AllowOfflineAccess"); | |||||
b.Property<bool>("AllowPlainTextPkce"); | |||||
b.Property<bool>("AllowRememberConsent"); | |||||
b.Property<bool>("AlwaysIncludeUserClaimsInIdToken"); | |||||
b.Property<bool>("AlwaysSendClientClaims"); | |||||
b.Property<int>("AuthorizationCodeLifetime"); | |||||
b.Property<string>("ClientId") | |||||
.IsRequired() | |||||
.HasMaxLength(200); | |||||
b.Property<string>("ClientName") | |||||
.HasMaxLength(200); | |||||
b.Property<string>("ClientUri") | |||||
.HasMaxLength(2000); | |||||
b.Property<bool>("EnableLocalLogin"); | |||||
b.Property<bool>("Enabled"); | |||||
b.Property<int>("IdentityTokenLifetime"); | |||||
b.Property<bool>("IncludeJwtId"); | |||||
b.Property<string>("LogoUri"); | |||||
b.Property<bool>("LogoutSessionRequired"); | |||||
b.Property<string>("LogoutUri"); | |||||
b.Property<bool>("PrefixClientClaims"); | |||||
b.Property<string>("ProtocolType") | |||||
.IsRequired() | |||||
.HasMaxLength(200); | |||||
b.Property<int>("RefreshTokenExpiration"); | |||||
b.Property<int>("RefreshTokenUsage"); | |||||
b.Property<bool>("RequireClientSecret"); | |||||
b.Property<bool>("RequireConsent"); | |||||
b.Property<bool>("RequirePkce"); | |||||
b.Property<int>("SlidingRefreshTokenLifetime"); | |||||
b.Property<bool>("UpdateAccessTokenClaimsOnRefresh"); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("ClientId") | |||||
.IsUnique(); | |||||
b.ToTable("Clients"); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientClaim", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<int?>("ClientId") | |||||
.IsRequired(); | |||||
b.Property<string>("Type") | |||||
.IsRequired() | |||||
.HasMaxLength(250); | |||||
b.Property<string>("Value") | |||||
.IsRequired() | |||||
.HasMaxLength(250); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("ClientId"); | |||||
b.ToTable("ClientClaims"); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientCorsOrigin", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<int?>("ClientId") | |||||
.IsRequired(); | |||||
b.Property<string>("Origin") | |||||
.IsRequired() | |||||
.HasMaxLength(150); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("ClientId"); | |||||
b.ToTable("ClientCorsOrigins"); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientGrantType", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<int?>("ClientId") | |||||
.IsRequired(); | |||||
b.Property<string>("GrantType") | |||||
.IsRequired() | |||||
.HasMaxLength(250); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("ClientId"); | |||||
b.ToTable("ClientGrantTypes"); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientIdPRestriction", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<int?>("ClientId") | |||||
.IsRequired(); | |||||
b.Property<string>("Provider") | |||||
.IsRequired() | |||||
.HasMaxLength(200); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("ClientId"); | |||||
b.ToTable("ClientIdPRestrictions"); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientPostLogoutRedirectUri", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<int?>("ClientId") | |||||
.IsRequired(); | |||||
b.Property<string>("PostLogoutRedirectUri") | |||||
.IsRequired() | |||||
.HasMaxLength(2000); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("ClientId"); | |||||
b.ToTable("ClientPostLogoutRedirectUris"); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientRedirectUri", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<int?>("ClientId") | |||||
.IsRequired(); | |||||
b.Property<string>("RedirectUri") | |||||
.IsRequired() | |||||
.HasMaxLength(2000); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("ClientId"); | |||||
b.ToTable("ClientRedirectUris"); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientScope", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<int?>("ClientId") | |||||
.IsRequired(); | |||||
b.Property<string>("Scope") | |||||
.IsRequired() | |||||
.HasMaxLength(200); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("ClientId"); | |||||
b.ToTable("ClientScopes"); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientSecret", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<int?>("ClientId") | |||||
.IsRequired(); | |||||
b.Property<string>("Description") | |||||
.HasMaxLength(2000); | |||||
b.Property<DateTime?>("Expiration"); | |||||
b.Property<string>("Type") | |||||
.HasMaxLength(250); | |||||
b.Property<string>("Value") | |||||
.IsRequired() | |||||
.HasMaxLength(2000); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("ClientId"); | |||||
b.ToTable("ClientSecrets"); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityClaim", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<int?>("IdentityResourceId") | |||||
.IsRequired(); | |||||
b.Property<string>("Type") | |||||
.IsRequired() | |||||
.HasMaxLength(200); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("IdentityResourceId"); | |||||
b.ToTable("IdentityClaims"); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityResource", b => | |||||
{ | |||||
b.Property<int>("Id") | |||||
.ValueGeneratedOnAdd(); | |||||
b.Property<string>("Description") | |||||
.HasMaxLength(1000); | |||||
b.Property<string>("DisplayName") | |||||
.HasMaxLength(200); | |||||
b.Property<bool>("Emphasize"); | |||||
b.Property<bool>("Enabled"); | |||||
b.Property<string>("Name") | |||||
.IsRequired() | |||||
.HasMaxLength(200); | |||||
b.Property<bool>("Required"); | |||||
b.Property<bool>("ShowInDiscoveryDocument"); | |||||
b.HasKey("Id"); | |||||
b.HasIndex("Name") | |||||
.IsUnique(); | |||||
b.ToTable("IdentityResources"); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceClaim", b => | |||||
{ | |||||
b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource") | |||||
.WithMany("UserClaims") | |||||
.HasForeignKey("ApiResourceId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScope", b => | |||||
{ | |||||
b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource") | |||||
.WithMany("Scopes") | |||||
.HasForeignKey("ApiResourceId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScopeClaim", b => | |||||
{ | |||||
b.HasOne("IdentityServer4.EntityFramework.Entities.ApiScope", "ApiScope") | |||||
.WithMany("UserClaims") | |||||
.HasForeignKey("ApiScopeId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiSecret", b => | |||||
{ | |||||
b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource") | |||||
.WithMany("Secrets") | |||||
.HasForeignKey("ApiResourceId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientClaim", b => | |||||
{ | |||||
b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") | |||||
.WithMany("Claims") | |||||
.HasForeignKey("ClientId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientCorsOrigin", b => | |||||
{ | |||||
b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") | |||||
.WithMany("AllowedCorsOrigins") | |||||
.HasForeignKey("ClientId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientGrantType", b => | |||||
{ | |||||
b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") | |||||
.WithMany("AllowedGrantTypes") | |||||
.HasForeignKey("ClientId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientIdPRestriction", b => | |||||
{ | |||||
b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") | |||||
.WithMany("IdentityProviderRestrictions") | |||||
.HasForeignKey("ClientId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientPostLogoutRedirectUri", b => | |||||
{ | |||||
b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") | |||||
.WithMany("PostLogoutRedirectUris") | |||||
.HasForeignKey("ClientId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientRedirectUri", b => | |||||
{ | |||||
b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") | |||||
.WithMany("RedirectUris") | |||||
.HasForeignKey("ClientId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientScope", b => | |||||
{ | |||||
b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") | |||||
.WithMany("AllowedScopes") | |||||
.HasForeignKey("ClientId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientSecret", b => | |||||
{ | |||||
b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") | |||||
.WithMany("ClientSecrets") | |||||
.HasForeignKey("ClientId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
}); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityClaim", b => | |||||
{ | |||||
b.HasOne("IdentityServer4.EntityFramework.Entities.IdentityResource", "IdentityResource") | |||||
.WithMany("UserClaims") | |||||
.HasForeignKey("IdentityResourceId") | |||||
.OnDelete(DeleteBehavior.Cascade); | |||||
}); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,51 @@ | |||||
using System; | |||||
using Microsoft.EntityFrameworkCore; | |||||
using Microsoft.EntityFrameworkCore.Infrastructure; | |||||
using Microsoft.EntityFrameworkCore.Metadata; | |||||
using Microsoft.EntityFrameworkCore.Migrations; | |||||
using IdentityServer4.EntityFramework.DbContexts; | |||||
namespace Identity.API.Migrations | |||||
{ | |||||
[DbContext(typeof(PersistedGrantDbContext))] | |||||
partial class PersistedGrantDbContextModelSnapshot : ModelSnapshot | |||||
{ | |||||
protected override void BuildModel(ModelBuilder modelBuilder) | |||||
{ | |||||
modelBuilder | |||||
.HasAnnotation("ProductVersion", "1.1.2") | |||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); | |||||
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.PersistedGrant", b => | |||||
{ | |||||
b.Property<string>("Key") | |||||
.HasMaxLength(200); | |||||
b.Property<string>("ClientId") | |||||
.IsRequired() | |||||
.HasMaxLength(200); | |||||
b.Property<DateTime>("CreationTime"); | |||||
b.Property<string>("Data") | |||||
.IsRequired() | |||||
.HasMaxLength(50000); | |||||
b.Property<DateTime?>("Expiration"); | |||||
b.Property<string>("SubjectId") | |||||
.HasMaxLength(200); | |||||
b.Property<string>("Type") | |||||
.IsRequired() | |||||
.HasMaxLength(50); | |||||
b.HasKey("Key"); | |||||
b.HasIndex("SubjectId", "ClientId", "Type"); | |||||
b.ToTable("PersistedGrants"); | |||||
}); | |||||
} | |||||
} | |||||
} |