使用客户凭证保护API

这篇快速开始将展示使用IdentityServer保护APIs的最基本使用场景.

在此场景中我们将定义一个API和一个要访问此API的客户端. 客户端将向IdentityServer 请求 access token 并用来 API.

定义 API

Scopes 定义了受保护的资源, 例如. APIs.

因为这里我们使用的是内存配置 - 需要添加一个 API, 创建一个 ApiResource 类型并设置相关属性.

添加一个类 (如. Config.cs) 到项目中并添加以下代码:

public static IEnumerable<ApiResource> GetApiResources()
{
    return new List<ApiResource>
    {
        new ApiResource("api1", "My API")
    };
}

定义客户client

下一步是定义一个能够访问此 API 的客户.

在此场景下, 客户不是一个真正可交互的用户, 而且使用所谓的密码通过IdentityServer进行授权 . 添加以下代码到 Config.cs 中:

public static IEnumerable<Client> GetClients()
{
    return new List<Client>
    {
        new Client
        {
            ClientId = "client",

            // no interactive user, use the clientid/secret for authentication
            AllowedGrantTypes = GrantTypes.ClientCredentials,

            // secret for authentication
            ClientSecrets =
            {
                new Secret("secret".Sha256())
            },

            // scopes that client has access to
            AllowedScopes = { "api1" }
        }
    };
}

配置 IdentityServer

为了使用以上配置的scopes 和客户来配置 IdentityServer , 需要添加以下代码到 ConfigureServices 方法中. 也可以使用方便的扩展方法将相关的存储和数据添加到依赖注入系统中:

public void ConfigureServices(IServiceCollection services)
{
    // configure identity server with in-memory stores, keys, clients and resources
    services.AddIdentityServer()
        .AddTemporarySigningCredential()
        .AddInMemoryApiResources(Config.GetApiResources())
        .AddInMemoryClients(Config.GetClients());
}

就是这样 - 如果现在打开浏览器到 http://localhost:5000/.well-known/openid-configuration, 你将看到所谓的发现文档. 这将提供客户端和 APIs 下载相关的配置数据.

添加一个 API 项目

下一步添加一个 API 项目到解决方案中.

可以使用 ASP.NET Core Web API 模板, 或者添加 Microsoft.AspNetCore.Mvc 包到项目中. 同样, 推荐和之前一样使用自己定义的端口及配置启动. 这里配置 API 到 http://localhost:5001.

控制器

添加一个 controller 到 API 项目:

[Route("identity")]
[Authorize]
public class IdentityController : ControllerBase
{
    [HttpGet]
    public IActionResult Get()
    {
        return new JsonResult(from c in User.Claims select new { c.Type, c.Value });
    }
}

此控制器将在后面授权请求的时候用到.

配置

最后一步是添加授权中间件到 API host. 中间件的任务是:

  • 验证传入的 token 以便确认是来自一个可信的客户
  • 验证 token 是否对此 api 有效 (即 scope)

添加 IdentityServer4.AccessTokenValidation NuGet 包到项目中.

同样需要将中间件添加到管道中. 并且在 MVC 之前.

public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
{
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();

    app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
    {
        Authority = "http://localhost:5000",
        RequireHttpsMetadata = false,

        ApiName = "api1"
    });

    app.UseMvc();
}

用浏览器导航到 (http://localhost:5001/identity), 将得到一个 401 状态码. 以为这 API 需要一个凭证.

这样, API 就被 IdentityServer 保护起来了.

创建 client

最后一步是创建一个客户请求 access token, 并用此 token 来访问 API. 为此,创建一个控制台应用程序.

IdentityServer 的token终结点实现了 OAuth 2.0 协议, 可以用原生 HTTP 来访问. 当然, 我们有一个名为 IdentityModel 的客户端类, 封装了交互协议以便方便的使用 API.

添加 IdentityModel NuGet 包到应用中.

IdentityModel 定义了一个客户类来发现终结点. 这样只需要 IdentityServer 的基本地址- 具体的地址可以在元数据中读出:

// discover endpoints from metadata
var disco = await DiscoveryClient.GetAsync("http://localhost:5000");

下一步使用 TokenClient 来请求 token. 需要传入 token 终结点地址, client id 和secret 创建一个实例.

下一步 RequestClientCredentialsAsync 来请求访问 API的token :

// request token
var tokenClient = new TokenClient(disco.TokenEndpoint, "client", "secret");
var tokenResponse = await tokenClient.RequestClientCredentialsAsync("api1");

if (tokenResponse.IsError)
{
    Console.WriteLine(tokenResponse.Error);
    return;
}

Console.WriteLine(tokenResponse.Json);

注意

从控制台复制 access token 到jwt.io 来检查原始 token.

最后一步就是调用 API.

使用 HTTP Authorization header发送access token到API . 这里使用 SetBearerToken 扩展方法:

// call api
var client = new HttpClient();
client.SetBearerToken(tokenResponse.AccessToken);

var response = await client.GetAsync("http://localhost:5001/identity");
if (!response.IsSuccessStatusCode)
{
    Console.WriteLine(response.StatusCode);
}
else
{
    var content = await response.Content.ReadAsStringAsync();
    Console.WriteLine(JArray.Parse(content));
}

输出如下:

注意

默认情况下  access token 包括 scope, lifetime (nbf and exp), the client ID (client_id) 和 the issuer name (iss).

进一步探索

这里关心的是以下两点

  • client 能够请求 token
  • client 能够使用 token 访问 API

可以尝试引发错误来看系统如何响应, e.g.

  • 试着在IdentityServer 没有启动时访问 (unavailable)
  • 试着使用无效的 client id 或 secret 来请求 token
  • 试着使用无效的 scope 请求
  • 试着在 API 没有启动时调用 (unavailable)
  • 调用 API时不发送token
  • 配置一个需要token中不同的scope 的 API

流程分析

1.客户端访问Server的http://localhost:5000/.well-known/openid-configuration以发现元数据

2.调用http://localhost:5000/connect/token获取token

3.请求资源API时,API验证token

Using EntityFramework Core for configuration and operational data

注意在Startup--Configure中注释原来的认证

            //app.UseAuthentication();
            app.UseIdentityServer();        

还有需要加上AddAspNetIdentity< ApplicationUser>

此处需要添加IdentityServer4.AspNetIdentity 包引用

// This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            var connectionString = Configuration.GetConnectionString("DefaultConnection");
            var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;
            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseMySQL(connectionString));

            services.AddDbContext<ConfigurationDbContext>(options =>
                options.UseMySQL(connectionString));

            services.AddIdentity<ApplicationUser, IdentityRole>()
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddDefaultTokenProviders();

            // Add application services.
            services.AddTransient<IEmailSender, EmailSender>();

            services.AddMvc();

            // configure identity server with in-memory stores, keys, clients and scopes
            services.AddIdentityServer()
                .AddDeveloperSigningCredential()
                .AddTestUsers(Config.GetUsers())
                // this adds the config data from DB (clients, resources)
                .AddConfigurationStore(options =>
                {
                    options.ConfigureDbContext = builder =>
                        builder.UseMySQL(connectionString,
                            sql => sql.MigrationsAssembly(migrationsAssembly));
                })
                // this adds the operational data from DB (codes, tokens, consents)
                .AddOperationalStore(options =>
                {
                    options.ConfigureDbContext = builder =>
                        builder.UseMySQL(connectionString,
                            sql => sql.MigrationsAssembly(migrationsAssembly));

                    // this enables automatic token cleanup. this is optional.
                    options.EnableTokenCleanup = true;
                                options.TokenCleanupInterval = ;
                 })
                 .AddAspNetIdentity< ApplicationUser>();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            //InitializeDatabase(app);
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseBrowserLink();
                app.UseDatabaseErrorPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }

            app.UseStaticFiles();

            //app.UseAuthentication();
            app.UseIdentityServer();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }

按上面的教程配置后在Web目录使用Power shell执行

dotnet ef migrations add InitialIdentityServerPersistedGrantDbMigration -c PersistedGrantDbContext -o Data/Migrations/IdentityServer/PersistedGrantDb
dotnet ef migrations add InitialIdentityServerConfigurationDbMigration -c ConfigurationDbContext -o Data/Migrations/IdentityServer/ConfigurationDb

或者在包管理控制台执行

add-migration InitialIdentityServerConfigurationDbMigration -c ConfigurationDbContext -o Migrations/IdentityServer/ConfigurationDb
add-migration  InitialIdentityServerPersistedGrantDbMigration -c PersistedGrantDbContext -o Migrations/IdentityServer/PersistedGrantDb

这里如果报错的话先在包管理控制台执行ApplicationDbContext的更新

PM> update-database -Context ApplicationDbContext

然后再执行Power shell

执行完成后直接运行即可。

如果不能自动建库,可以在包管理控制台输入

update-database -Context PersistedGrantDbContext
update-database -Context ConfigurationDbContext

MySQL建库脚本

/*
Navicat MySQL Data Transfer

Source Server         : mysql
Source Server Version : 50718
Source Host           : 192.168.31.146:3306
Source Database       : center

Target Server Type    : MYSQL
Target Server Version : 50718
File Encoding         : 65001

Date: 2018-01-30 22:21:56
*/

SET FOREIGN_KEY_CHECKS=;

-- ----------------------------
-- Table structure for __EFMigrationsHistory
-- ----------------------------
DROP TABLE IF EXISTS `__EFMigrationsHistory`;
CREATE TABLE `__EFMigrationsHistory` (
  `MigrationId` varchar() NOT NULL,
  `ProductVersion` varchar() NOT NULL,
  PRIMARY KEY (`MigrationId`)
) ;

-- ----------------------------
-- Table structure for ApiClaims
-- ----------------------------
DROP TABLE IF EXISTS `ApiClaims`;
CREATE TABLE `ApiClaims` (
  `Id` ) NOT NULL AUTO_INCREMENT,
  `ApiResourceId` ) NOT NULL,
  `Type` varchar() NOT NULL,
  PRIMARY KEY (`Id`),
  KEY `IX_ApiClaims_ApiResourceId` (`ApiResourceId`),
  CONSTRAINT `FK_ApiClaims_ApiResources_ApiResourceId` FOREIGN KEY (`ApiResourceId`) REFERENCES `ApiResources` (`Id`) ON DELETE CASCADE
) ;

-- ----------------------------
-- Table structure for ApiResources
-- ----------------------------
DROP TABLE IF EXISTS `ApiResources`;
CREATE TABLE `ApiResources` (
  `Id` ) NOT NULL AUTO_INCREMENT,
  `Description` varchar() DEFAULT NULL,
  `DisplayName` varchar() DEFAULT NULL,
  `Enabled` bit() NOT NULL,
  `Name` varchar() NOT NULL,
  PRIMARY KEY (`Id`),
  UNIQUE KEY `IX_ApiResources_Name` (`Name`)
) ;

-- ----------------------------
-- Table structure for ApiScopeClaims
-- ----------------------------
DROP TABLE IF EXISTS `ApiScopeClaims`;
CREATE TABLE `ApiScopeClaims` (
  `Id` ) NOT NULL AUTO_INCREMENT,
  `ApiScopeId` ) NOT NULL,
  `Type` varchar() NOT NULL,
  PRIMARY KEY (`Id`),
  KEY `IX_ApiScopeClaims_ApiScopeId` (`ApiScopeId`),
  CONSTRAINT `FK_ApiScopeClaims_ApiScopes_ApiScopeId` FOREIGN KEY (`ApiScopeId`) REFERENCES `ApiScopes` (`Id`) ON DELETE CASCADE
) ;

-- ----------------------------
-- Table structure for ApiScopes
-- ----------------------------
DROP TABLE IF EXISTS `ApiScopes`;
CREATE TABLE `ApiScopes` (
  `Id` ) NOT NULL AUTO_INCREMENT,
  `ApiResourceId` ) NOT NULL,
  `Description` varchar() DEFAULT NULL,
  `DisplayName` varchar() DEFAULT NULL,
  `Emphasize` bit() NOT NULL,
  `Name` varchar() NOT NULL,
  `Required` bit() NOT NULL,
  `ShowInDiscoveryDocument` bit() NOT NULL,
  PRIMARY KEY (`Id`),
  UNIQUE KEY `IX_ApiScopes_Name` (`Name`),
  KEY `IX_ApiScopes_ApiResourceId` (`ApiResourceId`),
  CONSTRAINT `FK_ApiScopes_ApiResources_ApiResourceId` FOREIGN KEY (`ApiResourceId`) REFERENCES `ApiResources` (`Id`) ON DELETE CASCADE
) ;

-- ----------------------------
-- Table structure for ApiSecrets
-- ----------------------------
DROP TABLE IF EXISTS `ApiSecrets`;
CREATE TABLE `ApiSecrets` (
  `Id` ) NOT NULL AUTO_INCREMENT,
  `ApiResourceId` ) NOT NULL,
  `Description` varchar() DEFAULT NULL,
  `Expiration` datetime DEFAULT NULL,
  `Type` varchar() DEFAULT NULL,
  `Value` varchar() DEFAULT NULL,
  PRIMARY KEY (`Id`),
  KEY `IX_ApiSecrets_ApiResourceId` (`ApiResourceId`),
  CONSTRAINT `FK_ApiSecrets_ApiResources_ApiResourceId` FOREIGN KEY (`ApiResourceId`) REFERENCES `ApiResources` (`Id`) ON DELETE CASCADE
) ;

-- ----------------------------
-- Table structure for AspNetRoleClaims
-- ----------------------------
DROP TABLE IF EXISTS `AspNetRoleClaims`;
CREATE TABLE `AspNetRoleClaims` (
  `Id` ) NOT NULL,
  `ClaimType` text,
  `ClaimValue` text,
  `RoleId` varchar() NOT NULL,
  PRIMARY KEY (`Id`),
  KEY `IX_AspNetRoleClaims_RoleId` (`RoleId`),
  CONSTRAINT `FK_AspNetRoleClaims_AspNetRoles_RoleId` FOREIGN KEY (`RoleId`) REFERENCES `AspNetRoles` (`Id`) ON DELETE CASCADE
) ;

-- ----------------------------
-- Table structure for AspNetRoles
-- ----------------------------
DROP TABLE IF EXISTS `AspNetRoles`;
CREATE TABLE `AspNetRoles` (
  `Id` varchar() NOT NULL,
  `ConcurrencyStamp` text,
  `Name` varchar() DEFAULT NULL,
  `NormalizedName` varchar() DEFAULT NULL,
  PRIMARY KEY (`Id`),
  KEY `RoleNameIndex` (`NormalizedName`)
) ;

-- ----------------------------
-- Table structure for AspNetUserClaims
-- ----------------------------
DROP TABLE IF EXISTS `AspNetUserClaims`;
CREATE TABLE `AspNetUserClaims` (
  `Id` ) NOT NULL,
  `ClaimType` text,
  `ClaimValue` text,
  `UserId` varchar() NOT NULL,
  PRIMARY KEY (`Id`),
  KEY `IX_AspNetUserClaims_UserId` (`UserId`),
  CONSTRAINT `FK_AspNetUserClaims_AspNetUsers_UserId` FOREIGN KEY (`UserId`) REFERENCES `AspNetUsers` (`Id`) ON DELETE CASCADE
) ;

-- ----------------------------
-- Table structure for AspNetUserLogins
-- ----------------------------
DROP TABLE IF EXISTS `AspNetUserLogins`;
CREATE TABLE `AspNetUserLogins` (
  `LoginProvider` varchar() NOT NULL,
  `ProviderKey` varchar() NOT NULL,
  `ProviderDisplayName` text,
  `UserId` varchar() NOT NULL,
  PRIMARY KEY (`LoginProvider`,`ProviderKey`),
  KEY `IX_AspNetUserLogins_UserId` (`UserId`),
  CONSTRAINT `FK_AspNetUserLogins_AspNetUsers_UserId` FOREIGN KEY (`UserId`) REFERENCES `AspNetUsers` (`Id`) ON DELETE CASCADE
) ;

-- ----------------------------
-- Table structure for AspNetUserRoles
-- ----------------------------
DROP TABLE IF EXISTS `AspNetUserRoles`;
CREATE TABLE `AspNetUserRoles` (
  `UserId` varchar() NOT NULL,
  `RoleId` varchar() NOT NULL,
  PRIMARY KEY (`UserId`,`RoleId`),
  KEY `IX_AspNetUserRoles_RoleId` (`RoleId`),
  KEY `IX_AspNetUserRoles_UserId` (`UserId`),
  CONSTRAINT `FK_AspNetUserRoles_AspNetRoles_RoleId` FOREIGN KEY (`RoleId`) REFERENCES `AspNetRoles` (`Id`) ON DELETE CASCADE,
  CONSTRAINT `FK_AspNetUserRoles_AspNetUsers_UserId` FOREIGN KEY (`UserId`) REFERENCES `AspNetUsers` (`Id`) ON DELETE CASCADE
) ;

-- ----------------------------
-- Table structure for AspNetUsers
-- ----------------------------
DROP TABLE IF EXISTS `AspNetUsers`;
CREATE TABLE `AspNetUsers` (
  `Id` varchar() NOT NULL,
  `AccessFailedCount` ) NOT NULL,
  `ConcurrencyStamp` text,
  `Email` varchar() DEFAULT NULL,
  `EmailConfirmed` bit() NOT NULL,
  `LockoutEnabled` bit() NOT NULL,
  `LockoutEnd` timestamp NULL DEFAULT NULL,
  `NormalizedEmail` varchar() DEFAULT NULL,
  `NormalizedUserName` varchar() DEFAULT NULL,
  `PasswordHash` text,
  `PhoneNumber` text,
  `PhoneNumberConfirmed` bit() NOT NULL,
  `SecurityStamp` text,
  `TwoFactorEnabled` bit() NOT NULL,
  `UserName` varchar() DEFAULT NULL,
  PRIMARY KEY (`Id`),
  UNIQUE KEY `UserNameIndex` (`NormalizedUserName`),
  KEY `EmailIndex` (`NormalizedEmail`)
) ;

-- ----------------------------
-- Table structure for AspNetUserTokens
-- ----------------------------
DROP TABLE IF EXISTS `AspNetUserTokens`;
CREATE TABLE `AspNetUserTokens` (
  `UserId` varchar() NOT NULL,
  `LoginProvider` varchar() NOT NULL,
  `Name` varchar() NOT NULL,
  `Value` text,
  PRIMARY KEY (`UserId`,`LoginProvider`,`Name`)
) ;

-- ----------------------------
-- Table structure for ClientClaims
-- ----------------------------
DROP TABLE IF EXISTS `ClientClaims`;
CREATE TABLE `ClientClaims` (
  `Id` ) NOT NULL AUTO_INCREMENT,
  `ClientId` ) NOT NULL,
  `Type` varchar() NOT NULL,
  `Value` varchar() NOT NULL,
  PRIMARY KEY (`Id`),
  KEY `IX_ClientClaims_ClientId` (`ClientId`),
  CONSTRAINT `FK_ClientClaims_Clients_ClientId` FOREIGN KEY (`ClientId`) REFERENCES `Clients` (`Id`) ON DELETE CASCADE
) ;

-- ----------------------------
-- Table structure for ClientCorsOrigins
-- ----------------------------
DROP TABLE IF EXISTS `ClientCorsOrigins`;
CREATE TABLE `ClientCorsOrigins` (
  `Id` ) NOT NULL AUTO_INCREMENT,
  `ClientId` ) NOT NULL,
  `Origin` varchar() NOT NULL,
  PRIMARY KEY (`Id`),
  KEY `IX_ClientCorsOrigins_ClientId` (`ClientId`),
  CONSTRAINT `FK_ClientCorsOrigins_Clients_ClientId` FOREIGN KEY (`ClientId`) REFERENCES `Clients` (`Id`) ON DELETE CASCADE
) ;

-- ----------------------------
-- Table structure for ClientGrantTypes
-- ----------------------------
DROP TABLE IF EXISTS `ClientGrantTypes`;
CREATE TABLE `ClientGrantTypes` (
  `Id` ) NOT NULL AUTO_INCREMENT,
  `ClientId` ) NOT NULL,
  `GrantType` varchar() NOT NULL,
  PRIMARY KEY (`Id`),
  KEY `IX_ClientGrantTypes_ClientId` (`ClientId`),
  CONSTRAINT `FK_ClientGrantTypes_Clients_ClientId` FOREIGN KEY (`ClientId`) REFERENCES `Clients` (`Id`) ON DELETE CASCADE
) ;

-- ----------------------------
-- Table structure for ClientIdPRestrictions
-- ----------------------------
DROP TABLE IF EXISTS `ClientIdPRestrictions`;
CREATE TABLE `ClientIdPRestrictions` (
  `Id` ) NOT NULL AUTO_INCREMENT,
  `ClientId` ) NOT NULL,
  `Provider` varchar() NOT NULL,
  PRIMARY KEY (`Id`),
  KEY `IX_ClientIdPRestrictions_ClientId` (`ClientId`),
  CONSTRAINT `FK_ClientIdPRestrictions_Clients_ClientId` FOREIGN KEY (`ClientId`) REFERENCES `Clients` (`Id`) ON DELETE CASCADE
) ;

-- ----------------------------
-- Table structure for ClientPostLogoutRedirectUris
-- ----------------------------
DROP TABLE IF EXISTS `ClientPostLogoutRedirectUris`;
CREATE TABLE `ClientPostLogoutRedirectUris` (
  `Id` ) NOT NULL AUTO_INCREMENT,
  `ClientId` ) NOT NULL,
  `PostLogoutRedirectUri` varchar() NOT NULL,
  PRIMARY KEY (`Id`),
  KEY `IX_ClientPostLogoutRedirectUris_ClientId` (`ClientId`),
  CONSTRAINT `FK_ClientPostLogoutRedirectUris_Clients_ClientId` FOREIGN KEY (`ClientId`) REFERENCES `Clients` (`Id`) ON DELETE CASCADE
) ;

-- ----------------------------
-- Table structure for ClientProperties
-- ----------------------------
DROP TABLE IF EXISTS `ClientProperties`;
CREATE TABLE `ClientProperties` (
  `Id` ) NOT NULL AUTO_INCREMENT,
  `ClientId` ) NOT NULL,
  `Key` varchar() NOT NULL,
  `Value` varchar() NOT NULL,
  PRIMARY KEY (`Id`),
  KEY `IX_ClientProperties_ClientId` (`ClientId`),
  CONSTRAINT `FK_ClientProperties_Clients_ClientId` FOREIGN KEY (`ClientId`) REFERENCES `Clients` (`Id`) ON DELETE CASCADE
) ;

-- ----------------------------
-- Table structure for ClientRedirectUris
-- ----------------------------
DROP TABLE IF EXISTS `ClientRedirectUris`;
CREATE TABLE `ClientRedirectUris` (
  `Id` ) NOT NULL AUTO_INCREMENT,
  `ClientId` ) NOT NULL,
  `RedirectUri` varchar() NOT NULL,
  PRIMARY KEY (`Id`),
  KEY `IX_ClientRedirectUris_ClientId` (`ClientId`),
  CONSTRAINT `FK_ClientRedirectUris_Clients_ClientId` FOREIGN KEY (`ClientId`) REFERENCES `Clients` (`Id`) ON DELETE CASCADE
) ;

-- ----------------------------
-- Table structure for Clients
-- ----------------------------
DROP TABLE IF EXISTS `Clients`;
CREATE TABLE `Clients` (
  `Id` ) NOT NULL AUTO_INCREMENT,
  `AbsoluteRefreshTokenLifetime` ) NOT NULL,
  `AccessTokenLifetime` ) NOT NULL,
  `AccessTokenType` ) NOT NULL,
  `AllowAccessTokensViaBrowser` bit() NOT NULL,
  `AllowOfflineAccess` bit() NOT NULL,
  `AllowPlainTextPkce` bit() NOT NULL,
  `AllowRememberConsent` bit() NOT NULL,
  `AlwaysIncludeUserClaimsInIdToken` bit() NOT NULL,
  `AlwaysSendClientClaims` bit() NOT NULL,
  `AuthorizationCodeLifetime` ) NOT NULL,
  `BackChannelLogoutSessionRequired` bit() NOT NULL,
  `BackChannelLogoutUri` varchar() DEFAULT NULL,
  `ClientClaimsPrefix` varchar() DEFAULT NULL,
  `ClientId` varchar() NOT NULL,
  `ClientName` varchar() DEFAULT NULL,
  `ClientUri` varchar() DEFAULT NULL,
  `ConsentLifetime` ) DEFAULT NULL,
  `Description` varchar() DEFAULT NULL,
  `EnableLocalLogin` bit() NOT NULL,
  `Enabled` bit() NOT NULL,
  `FrontChannelLogoutSessionRequired` bit() NOT NULL,
  `FrontChannelLogoutUri` varchar() DEFAULT NULL,
  `IdentityTokenLifetime` ) NOT NULL,
  `IncludeJwtId` bit() NOT NULL,
  `LogoUri` varchar() DEFAULT NULL,
  `PairWiseSubjectSalt` varchar() DEFAULT NULL,
  `ProtocolType` varchar() NOT NULL,
  `RefreshTokenExpiration` ) NOT NULL,
  `RefreshTokenUsage` ) NOT NULL,
  `RequireClientSecret` bit() NOT NULL,
  `RequireConsent` bit() NOT NULL,
  `RequirePkce` bit() NOT NULL,
  `SlidingRefreshTokenLifetime` ) NOT NULL,
  `UpdateAccessTokenClaimsOnRefresh` bit() NOT NULL,
  PRIMARY KEY (`Id`),
  UNIQUE KEY `IX_Clients_ClientId` (`ClientId`)
) ;

-- ----------------------------
-- Table structure for ClientScopes
-- ----------------------------
DROP TABLE IF EXISTS `ClientScopes`;
CREATE TABLE `ClientScopes` (
  `Id` ) NOT NULL AUTO_INCREMENT,
  `ClientId` ) NOT NULL,
  `Scope` varchar() NOT NULL,
  PRIMARY KEY (`Id`),
  KEY `IX_ClientScopes_ClientId` (`ClientId`),
  CONSTRAINT `FK_ClientScopes_Clients_ClientId` FOREIGN KEY (`ClientId`) REFERENCES `Clients` (`Id`) ON DELETE CASCADE
) ;

-- ----------------------------
-- Table structure for ClientSecrets
-- ----------------------------
DROP TABLE IF EXISTS `ClientSecrets`;
CREATE TABLE `ClientSecrets` (
  `Id` ) NOT NULL AUTO_INCREMENT,
  `ClientId` ) NOT NULL,
  `Description` varchar() DEFAULT NULL,
  `Expiration` datetime DEFAULT NULL,
  `Type` varchar() DEFAULT NULL,
  `Value` varchar() NOT NULL,
  PRIMARY KEY (`Id`),
  KEY `IX_ClientSecrets_ClientId` (`ClientId`),
  CONSTRAINT `FK_ClientSecrets_Clients_ClientId` FOREIGN KEY (`ClientId`) REFERENCES `Clients` (`Id`) ON DELETE CASCADE
) ;

-- ----------------------------
-- Table structure for IdentityClaims
-- ----------------------------
DROP TABLE IF EXISTS `IdentityClaims`;
CREATE TABLE `IdentityClaims` (
  `Id` ) NOT NULL AUTO_INCREMENT,
  `IdentityResourceId` ) NOT NULL,
  `Type` varchar() NOT NULL,
  PRIMARY KEY (`Id`),
  KEY `IX_IdentityClaims_IdentityResourceId` (`IdentityResourceId`),
  CONSTRAINT `FK_IdentityClaims_IdentityResources_IdentityResourceId` FOREIGN KEY (`IdentityResourceId`) REFERENCES `IdentityResources` (`Id`) ON DELETE CASCADE
) ;

-- ----------------------------
-- Table structure for IdentityResources
-- ----------------------------
DROP TABLE IF EXISTS `IdentityResources`;
CREATE TABLE `IdentityResources` (
  `Id` ) NOT NULL AUTO_INCREMENT,
  `Description` varchar() DEFAULT NULL,
  `DisplayName` varchar() DEFAULT NULL,
  `Emphasize` bit() NOT NULL,
  `Enabled` bit() NOT NULL,
  `Name` varchar() NOT NULL,
  `Required` bit() NOT NULL,
  `ShowInDiscoveryDocument` bit() NOT NULL,
  PRIMARY KEY (`Id`),
  UNIQUE KEY `IX_IdentityResources_Name` (`Name`)
) ;

-- ----------------------------
-- Table structure for PersistedGrants
-- ----------------------------
DROP TABLE IF EXISTS `PersistedGrants`;
CREATE TABLE `PersistedGrants` (
  `Key` varchar() NOT NULL,
  `ClientId` varchar() NOT NULL,
  `CreationTime` datetime NOT NULL,
  `Data` varchar() NOT NULL,
  `Expiration` datetime DEFAULT NULL,
  `SubjectId` varchar() DEFAULT NULL,
  `Type` varchar() NOT NULL,
  PRIMARY KEY (`Key`),
  KEY `IX_PersistedGrants_SubjectId_ClientId_Type` (`SubjectId`,`ClientId`,`Type`)
) ;

SqlServer建库脚本https://github.com/IdentityServer/IdentityServer4.EntityFramework/blob/dev/src/Host/Migrations/IdentityServer/ConfigurationDb.sql

IF OBJECT_ID(N'__EFMigrationsHistory') IS NULL
BEGIN
    CREATE TABLE [__EFMigrationsHistory] (
        [MigrationId] nvarchar() NOT NULL,
        [ProductVersion] nvarchar() NOT NULL,
        CONSTRAINT [PK___EFMigrationsHistory] PRIMARY KEY ([MigrationId])
    );
END;

GO

CREATE TABLE [ApiResources] (
    [Id] int NOT NULL IDENTITY,
    [Description] nvarchar() NULL,
    [DisplayName] nvarchar() NULL,
    [Enabled] bit NOT NULL,
    [Name] nvarchar() NOT NULL,
    CONSTRAINT [PK_ApiResources] PRIMARY KEY ([Id])
);

GO

CREATE TABLE [Clients] (
    [Id] int NOT NULL IDENTITY,
    [AbsoluteRefreshTokenLifetime] int NOT NULL,
    [AccessTokenLifetime] int NOT NULL,
    [AccessTokenType] int NOT NULL,
    [AllowAccessTokensViaBrowser] bit NOT NULL,
    [AllowOfflineAccess] bit NOT NULL,
    [AllowPlainTextPkce] bit NOT NULL,
    [AllowRememberConsent] bit NOT NULL,
    [AlwaysIncludeUserClaimsInIdToken] bit NOT NULL,
    [AlwaysSendClientClaims] bit NOT NULL,
    [AuthorizationCodeLifetime] int NOT NULL,
    [BackChannelLogoutSessionRequired] bit NOT NULL,
    [BackChannelLogoutUri] nvarchar() NULL,
    [ClientClaimsPrefix] nvarchar() NULL,
    [ClientId] nvarchar() NOT NULL,
    [ClientName] nvarchar() NULL,
    [ClientUri] nvarchar() NULL,
    [ConsentLifetime] int NULL,
    [Description] nvarchar() NULL,
    [EnableLocalLogin] bit NOT NULL,
    [Enabled] bit NOT NULL,
    [FrontChannelLogoutSessionRequired] bit NOT NULL,
    [FrontChannelLogoutUri] nvarchar() NULL,
    [IdentityTokenLifetime] int NOT NULL,
    [IncludeJwtId] bit NOT NULL,
    [LogoUri] nvarchar() NULL,
    [PairWiseSubjectSalt] nvarchar() NULL,
    [ProtocolType] nvarchar() NOT NULL,
    [RefreshTokenExpiration] int NOT NULL,
    [RefreshTokenUsage] int NOT NULL,
    [RequireClientSecret] bit NOT NULL,
    [RequireConsent] bit NOT NULL,
    [RequirePkce] bit NOT NULL,
    [SlidingRefreshTokenLifetime] int NOT NULL,
    [UpdateAccessTokenClaimsOnRefresh] bit NOT NULL,
    CONSTRAINT [PK_Clients] PRIMARY KEY ([Id])
);

GO

CREATE TABLE [IdentityResources] (
    [Id] int NOT NULL IDENTITY,
    [Description] nvarchar() NULL,
    [DisplayName] nvarchar() NULL,
    [Emphasize] bit NOT NULL,
    [Enabled] bit NOT NULL,
    [Name] nvarchar() NOT NULL,
    [Required] bit NOT NULL,
    [ShowInDiscoveryDocument] bit NOT NULL,
    CONSTRAINT [PK_IdentityResources] PRIMARY KEY ([Id])
);

GO

CREATE TABLE [ApiClaims] (
    [Id] int NOT NULL IDENTITY,
    [ApiResourceId] int NOT NULL,
    [Type] nvarchar() NOT NULL,
    CONSTRAINT [PK_ApiClaims] PRIMARY KEY ([Id]),
    CONSTRAINT [FK_ApiClaims_ApiResources_ApiResourceId] FOREIGN KEY ([ApiResourceId]) REFERENCES [ApiResources] ([Id]) ON DELETE CASCADE
);

GO

CREATE TABLE [ApiScopes] (
    [Id] int NOT NULL IDENTITY,
    [ApiResourceId] int NOT NULL,
    [Description] nvarchar() NULL,
    [DisplayName] nvarchar() NULL,
    [Emphasize] bit NOT NULL,
    [Name] nvarchar() NOT NULL,
    [Required] bit NOT NULL,
    [ShowInDiscoveryDocument] bit NOT NULL,
    CONSTRAINT [PK_ApiScopes] PRIMARY KEY ([Id]),
    CONSTRAINT [FK_ApiScopes_ApiResources_ApiResourceId] FOREIGN KEY ([ApiResourceId]) REFERENCES [ApiResources] ([Id]) ON DELETE CASCADE
);

GO

CREATE TABLE [ApiSecrets] (
    [Id] int NOT NULL IDENTITY,
    [ApiResourceId] int NOT NULL,
    [Description] nvarchar() NULL,
    [Expiration] datetime2 NULL,
    [Type] nvarchar() NULL,
    [Value] nvarchar() NULL,
    CONSTRAINT [PK_ApiSecrets] PRIMARY KEY ([Id]),
    CONSTRAINT [FK_ApiSecrets_ApiResources_ApiResourceId] FOREIGN KEY ([ApiResourceId]) REFERENCES [ApiResources] ([Id]) ON DELETE CASCADE
);

GO

CREATE TABLE [ClientClaims] (
    [Id] int NOT NULL IDENTITY,
    [ClientId] int NOT NULL,
    [Type] nvarchar() NOT NULL,
    [Value] nvarchar() NOT NULL,
    CONSTRAINT [PK_ClientClaims] PRIMARY KEY ([Id]),
    CONSTRAINT [FK_ClientClaims_Clients_ClientId] FOREIGN KEY ([ClientId]) REFERENCES [Clients] ([Id]) ON DELETE CASCADE
);

GO

CREATE TABLE [ClientCorsOrigins] (
    [Id] int NOT NULL IDENTITY,
    [ClientId] int NOT NULL,
    [Origin] nvarchar() NOT NULL,
    CONSTRAINT [PK_ClientCorsOrigins] PRIMARY KEY ([Id]),
    CONSTRAINT [FK_ClientCorsOrigins_Clients_ClientId] FOREIGN KEY ([ClientId]) REFERENCES [Clients] ([Id]) ON DELETE CASCADE
);

GO

CREATE TABLE [ClientGrantTypes] (
    [Id] int NOT NULL IDENTITY,
    [ClientId] int NOT NULL,
    [GrantType] nvarchar() NOT NULL,
    CONSTRAINT [PK_ClientGrantTypes] PRIMARY KEY ([Id]),
    CONSTRAINT [FK_ClientGrantTypes_Clients_ClientId] FOREIGN KEY ([ClientId]) REFERENCES [Clients] ([Id]) ON DELETE CASCADE
);

GO

CREATE TABLE [ClientIdPRestrictions] (
    [Id] int NOT NULL IDENTITY,
    [ClientId] int NOT NULL,
    [Provider] nvarchar() NOT NULL,
    CONSTRAINT [PK_ClientIdPRestrictions] PRIMARY KEY ([Id]),
    CONSTRAINT [FK_ClientIdPRestrictions_Clients_ClientId] FOREIGN KEY ([ClientId]) REFERENCES [Clients] ([Id]) ON DELETE CASCADE
);

GO

CREATE TABLE [ClientPostLogoutRedirectUris] (
    [Id] int NOT NULL IDENTITY,
    [ClientId] int NOT NULL,
    [PostLogoutRedirectUri] nvarchar() NOT NULL,
    CONSTRAINT [PK_ClientPostLogoutRedirectUris] PRIMARY KEY ([Id]),
    CONSTRAINT [FK_ClientPostLogoutRedirectUris_Clients_ClientId] FOREIGN KEY ([ClientId]) REFERENCES [Clients] ([Id]) ON DELETE CASCADE
);

GO

CREATE TABLE [ClientProperties] (
    [Id] int NOT NULL IDENTITY,
    [ClientId] int NOT NULL,
    [Key] nvarchar() NOT NULL,
    [Value] nvarchar() NOT NULL,
    CONSTRAINT [PK_ClientProperties] PRIMARY KEY ([Id]),
    CONSTRAINT [FK_ClientProperties_Clients_ClientId] FOREIGN KEY ([ClientId]) REFERENCES [Clients] ([Id]) ON DELETE CASCADE
);

GO

CREATE TABLE [ClientRedirectUris] (
    [Id] int NOT NULL IDENTITY,
    [ClientId] int NOT NULL,
    [RedirectUri] nvarchar() NOT NULL,
    CONSTRAINT [PK_ClientRedirectUris] PRIMARY KEY ([Id]),
    CONSTRAINT [FK_ClientRedirectUris_Clients_ClientId] FOREIGN KEY ([ClientId]) REFERENCES [Clients] ([Id]) ON DELETE CASCADE
);

GO

CREATE TABLE [ClientScopes] (
    [Id] int NOT NULL IDENTITY,
    [ClientId] int NOT NULL,
    [Scope] nvarchar() NOT NULL,
    CONSTRAINT [PK_ClientScopes] PRIMARY KEY ([Id]),
    CONSTRAINT [FK_ClientScopes_Clients_ClientId] FOREIGN KEY ([ClientId]) REFERENCES [Clients] ([Id]) ON DELETE CASCADE
);

GO

CREATE TABLE [ClientSecrets] (
    [Id] int NOT NULL IDENTITY,
    [ClientId] int NOT NULL,
    [Description] nvarchar() NULL,
    [Expiration] datetime2 NULL,
    [Type] nvarchar() NULL,
    [Value] nvarchar() NOT NULL,
    CONSTRAINT [PK_ClientSecrets] PRIMARY KEY ([Id]),
    CONSTRAINT [FK_ClientSecrets_Clients_ClientId] FOREIGN KEY ([ClientId]) REFERENCES [Clients] ([Id]) ON DELETE CASCADE
);

GO

CREATE TABLE [IdentityClaims] (
    [Id] int NOT NULL IDENTITY,
    [IdentityResourceId] int NOT NULL,
    [Type] nvarchar() NOT NULL,
    CONSTRAINT [PK_IdentityClaims] PRIMARY KEY ([Id]),
    CONSTRAINT [FK_IdentityClaims_IdentityResources_IdentityResourceId] FOREIGN KEY ([IdentityResourceId]) REFERENCES [IdentityResources] ([Id]) ON DELETE CASCADE
);

GO

CREATE TABLE [ApiScopeClaims] (
    [Id] int NOT NULL IDENTITY,
    [ApiScopeId] int NOT NULL,
    [Type] nvarchar() NOT NULL,
    CONSTRAINT [PK_ApiScopeClaims] PRIMARY KEY ([Id]),
    CONSTRAINT [FK_ApiScopeClaims_ApiScopes_ApiScopeId] FOREIGN KEY ([ApiScopeId]) REFERENCES [ApiScopes] ([Id]) ON DELETE CASCADE
);

GO

CREATE INDEX [IX_ApiClaims_ApiResourceId] ON [ApiClaims] ([ApiResourceId]);

GO

CREATE UNIQUE INDEX [IX_ApiResources_Name] ON [ApiResources] ([Name]);

GO

CREATE INDEX [IX_ApiScopeClaims_ApiScopeId] ON [ApiScopeClaims] ([ApiScopeId]);

GO

CREATE INDEX [IX_ApiScopes_ApiResourceId] ON [ApiScopes] ([ApiResourceId]);

GO

CREATE UNIQUE INDEX [IX_ApiScopes_Name] ON [ApiScopes] ([Name]);

GO

CREATE INDEX [IX_ApiSecrets_ApiResourceId] ON [ApiSecrets] ([ApiResourceId]);

GO

CREATE INDEX [IX_ClientClaims_ClientId] ON [ClientClaims] ([ClientId]);

GO

CREATE INDEX [IX_ClientCorsOrigins_ClientId] ON [ClientCorsOrigins] ([ClientId]);

GO

CREATE INDEX [IX_ClientGrantTypes_ClientId] ON [ClientGrantTypes] ([ClientId]);

GO

CREATE INDEX [IX_ClientIdPRestrictions_ClientId] ON [ClientIdPRestrictions] ([ClientId]);

GO

CREATE INDEX [IX_ClientPostLogoutRedirectUris_ClientId] ON [ClientPostLogoutRedirectUris] ([ClientId]);

GO

CREATE INDEX [IX_ClientProperties_ClientId] ON [ClientProperties] ([ClientId]);

GO

CREATE INDEX [IX_ClientRedirectUris_ClientId] ON [ClientRedirectUris] ([ClientId]);

GO

CREATE UNIQUE INDEX [IX_Clients_ClientId] ON [Clients] ([ClientId]);

GO

CREATE INDEX [IX_ClientScopes_ClientId] ON [ClientScopes] ([ClientId]);

GO

CREATE INDEX [IX_ClientSecrets_ClientId] ON [ClientSecrets] ([ClientId]);

GO

CREATE INDEX [IX_IdentityClaims_IdentityResourceId] ON [IdentityClaims] ([IdentityResourceId]);

GO

CREATE UNIQUE INDEX [IX_IdentityResources_Name] ON [IdentityResources] ([Name]);

GO

INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
VALUES (N'20170927170433_Config', N'2.0.0-rtm-26452');

GO

PostgreSql

/*
 Navicat Premium Data Transfer

 Source Server         : 10.15.4.155
 Source Server Type    : PostgreSQL
 Source Server Version : 100001
 Source Host           : 10.15.4.155:5432
 Source Catalog        : postgres
 Source Schema         : public

 Target Server Type    : PostgreSQL
 Target Server Version : 100001
 File Encoding         : 65001

 Date: 07/02/2018 12:35:06
*/

-- ----------------------------
-- Sequence structure for ApiClaims_Id_seq
-- ----------------------------
DROP SEQUENCE IF EXISTS "public"."ApiClaims_Id_seq";
CREATE SEQUENCE "public"."ApiClaims_Id_seq"
INCREMENT
MINVALUE
MAXVALUE
START
CACHE ;

-- ----------------------------
-- Sequence structure for ApiResources_Id_seq
-- ----------------------------
DROP SEQUENCE IF EXISTS "public"."ApiResources_Id_seq";
CREATE SEQUENCE "public"."ApiResources_Id_seq"
INCREMENT
MINVALUE
MAXVALUE
START
CACHE ;

-- ----------------------------
-- Sequence structure for ApiScopeClaims_Id_seq
-- ----------------------------
DROP SEQUENCE IF EXISTS "public"."ApiScopeClaims_Id_seq";
CREATE SEQUENCE "public"."ApiScopeClaims_Id_seq"
INCREMENT
MINVALUE
MAXVALUE
START
CACHE ;

-- ----------------------------
-- Sequence structure for ApiScopes_Id_seq
-- ----------------------------
DROP SEQUENCE IF EXISTS "public"."ApiScopes_Id_seq";
CREATE SEQUENCE "public"."ApiScopes_Id_seq"
INCREMENT
MINVALUE
MAXVALUE
START
CACHE ;

-- ----------------------------
-- Sequence structure for ApiSecrets_Id_seq
-- ----------------------------
DROP SEQUENCE IF EXISTS "public"."ApiSecrets_Id_seq";
CREATE SEQUENCE "public"."ApiSecrets_Id_seq"
INCREMENT
MINVALUE
MAXVALUE
START
CACHE ;

-- ----------------------------
-- Sequence structure for AspNetRoleClaims_Id_seq
-- ----------------------------
DROP SEQUENCE IF EXISTS "public"."AspNetRoleClaims_Id_seq";
CREATE SEQUENCE "public"."AspNetRoleClaims_Id_seq"
INCREMENT
MINVALUE
MAXVALUE
START
CACHE ;

-- ----------------------------
-- Sequence structure for AspNetUserClaims_Id_seq
-- ----------------------------
DROP SEQUENCE IF EXISTS "public"."AspNetUserClaims_Id_seq";
CREATE SEQUENCE "public"."AspNetUserClaims_Id_seq"
INCREMENT
MINVALUE
MAXVALUE
START
CACHE ;

-- ----------------------------
-- Sequence structure for ClientClaims_Id_seq
-- ----------------------------
DROP SEQUENCE IF EXISTS "public"."ClientClaims_Id_seq";
CREATE SEQUENCE "public"."ClientClaims_Id_seq"
INCREMENT
MINVALUE
MAXVALUE
START
CACHE ;

-- ----------------------------
-- Sequence structure for ClientCorsOrigins_Id_seq
-- ----------------------------
DROP SEQUENCE IF EXISTS "public"."ClientCorsOrigins_Id_seq";
CREATE SEQUENCE "public"."ClientCorsOrigins_Id_seq"
INCREMENT
MINVALUE
MAXVALUE
START
CACHE ;

-- ----------------------------
-- Sequence structure for ClientGrantTypes_Id_seq
-- ----------------------------
DROP SEQUENCE IF EXISTS "public"."ClientGrantTypes_Id_seq";
CREATE SEQUENCE "public"."ClientGrantTypes_Id_seq"
INCREMENT
MINVALUE
MAXVALUE
START
CACHE ;

-- ----------------------------
-- Sequence structure for ClientIdPRestrictions_Id_seq
-- ----------------------------
DROP SEQUENCE IF EXISTS "public"."ClientIdPRestrictions_Id_seq";
CREATE SEQUENCE "public"."ClientIdPRestrictions_Id_seq"
INCREMENT
MINVALUE
MAXVALUE
START
CACHE ;

-- ----------------------------
-- Sequence structure for ClientPostLogoutRedirectUris_Id_seq
-- ----------------------------
DROP SEQUENCE IF EXISTS "public"."ClientPostLogoutRedirectUris_Id_seq";
CREATE SEQUENCE "public"."ClientPostLogoutRedirectUris_Id_seq"
INCREMENT
MINVALUE
MAXVALUE
START
CACHE ;

-- ----------------------------
-- Sequence structure for ClientProperties_Id_seq
-- ----------------------------
DROP SEQUENCE IF EXISTS "public"."ClientProperties_Id_seq";
CREATE SEQUENCE "public"."ClientProperties_Id_seq"
INCREMENT
MINVALUE
MAXVALUE
START
CACHE ;

-- ----------------------------
-- Sequence structure for ClientRedirectUris_Id_seq
-- ----------------------------
DROP SEQUENCE IF EXISTS "public"."ClientRedirectUris_Id_seq";
CREATE SEQUENCE "public"."ClientRedirectUris_Id_seq"
INCREMENT
MINVALUE
MAXVALUE
START
CACHE ;

-- ----------------------------
-- Sequence structure for ClientScopes_Id_seq
-- ----------------------------
DROP SEQUENCE IF EXISTS "public"."ClientScopes_Id_seq";
CREATE SEQUENCE "public"."ClientScopes_Id_seq"
INCREMENT
MINVALUE
MAXVALUE
START
CACHE ;

-- ----------------------------
-- Sequence structure for ClientSecrets_Id_seq
-- ----------------------------
DROP SEQUENCE IF EXISTS "public"."ClientSecrets_Id_seq";
CREATE SEQUENCE "public"."ClientSecrets_Id_seq"
INCREMENT
MINVALUE
MAXVALUE
START
CACHE ;

-- ----------------------------
-- Sequence structure for Clients_Id_seq
-- ----------------------------
DROP SEQUENCE IF EXISTS "public"."Clients_Id_seq";
CREATE SEQUENCE "public"."Clients_Id_seq"
INCREMENT
MINVALUE
MAXVALUE
START
CACHE ;

-- ----------------------------
-- Sequence structure for IdentityClaims_Id_seq
-- ----------------------------
DROP SEQUENCE IF EXISTS "public"."IdentityClaims_Id_seq";
CREATE SEQUENCE "public"."IdentityClaims_Id_seq"
INCREMENT
MINVALUE
MAXVALUE
START
CACHE ;

-- ----------------------------
-- Sequence structure for IdentityResources_Id_seq
-- ----------------------------
DROP SEQUENCE IF EXISTS "public"."IdentityResources_Id_seq";
CREATE SEQUENCE "public"."IdentityResources_Id_seq"
INCREMENT
MINVALUE
MAXVALUE
START
CACHE ;

-- ----------------------------
-- Table structure for ApiClaims
-- ----------------------------
DROP TABLE IF EXISTS "public"."ApiClaims";
CREATE TABLE "public"."ApiClaims" (
  "Id" int4 NOT NULL DEFAULT nextval('"ApiClaims_Id_seq"'::regclass),
  "ApiResourceId" int4 NOT NULL,
  ) COLLATE "pg_catalog"."default" NOT NULL
)
;

-- ----------------------------
-- Table structure for ApiResources
-- ----------------------------
DROP TABLE IF EXISTS "public"."ApiResources";
CREATE TABLE "public"."ApiResources" (
  "Id" int4 NOT NULL DEFAULT nextval('"ApiResources_Id_seq"'::regclass),
  ) COLLATE "pg_catalog"."default",
  ) COLLATE "pg_catalog"."default",
  "Enabled" bool NOT NULL,
  ) COLLATE "pg_catalog"."default" NOT NULL
)
;

-- ----------------------------
-- Table structure for ApiScopeClaims
-- ----------------------------
DROP TABLE IF EXISTS "public"."ApiScopeClaims";
CREATE TABLE "public"."ApiScopeClaims" (
  "Id" int4 NOT NULL DEFAULT nextval('"ApiScopeClaims_Id_seq"'::regclass),
  "ApiScopeId" int4 NOT NULL,
  ) COLLATE "pg_catalog"."default" NOT NULL
)
;

-- ----------------------------
-- Table structure for ApiScopes
-- ----------------------------
DROP TABLE IF EXISTS "public"."ApiScopes";
CREATE TABLE "public"."ApiScopes" (
  "Id" int4 NOT NULL DEFAULT nextval('"ApiScopes_Id_seq"'::regclass),
  "ApiResourceId" int4 NOT NULL,
  ) COLLATE "pg_catalog"."default",
  ) COLLATE "pg_catalog"."default",
  "Emphasize" bool NOT NULL,
  ) COLLATE "pg_catalog"."default" NOT NULL,
  "Required" bool NOT NULL,
  "ShowInDiscoveryDocument" bool NOT NULL
)
;

-- ----------------------------
-- Table structure for ApiSecrets
-- ----------------------------
DROP TABLE IF EXISTS "public"."ApiSecrets";
CREATE TABLE "public"."ApiSecrets" (
  "Id" int4 NOT NULL DEFAULT nextval('"ApiSecrets_Id_seq"'::regclass),
  "ApiResourceId" int4 NOT NULL,
  ) COLLATE "pg_catalog"."default",
  ),
  ) COLLATE "pg_catalog"."default",
  ) COLLATE "pg_catalog"."default"
)
;

-- ----------------------------
-- Table structure for AspNetRoleClaims
-- ----------------------------
DROP TABLE IF EXISTS "public"."AspNetRoleClaims";
CREATE TABLE "public"."AspNetRoleClaims" (
  "Id" int4 NOT NULL DEFAULT nextval('"AspNetRoleClaims_Id_seq"'::regclass),
  "ClaimType" text COLLATE "pg_catalog"."default",
  "ClaimValue" text COLLATE "pg_catalog"."default",
  "RoleId" text COLLATE "pg_catalog"."default" NOT NULL
)
;

-- ----------------------------
-- Table structure for AspNetRoles
-- ----------------------------
DROP TABLE IF EXISTS "public"."AspNetRoles";
CREATE TABLE "public"."AspNetRoles" (
  "Id" text COLLATE "pg_catalog"."default" NOT NULL,
  "ConcurrencyStamp" text COLLATE "pg_catalog"."default",
  ) COLLATE "pg_catalog"."default",
  ) COLLATE "pg_catalog"."default"
)
;

-- ----------------------------
-- Table structure for AspNetUserClaims
-- ----------------------------
DROP TABLE IF EXISTS "public"."AspNetUserClaims";
CREATE TABLE "public"."AspNetUserClaims" (
  "Id" int4 NOT NULL DEFAULT nextval('"AspNetUserClaims_Id_seq"'::regclass),
  "ClaimType" text COLLATE "pg_catalog"."default",
  "ClaimValue" text COLLATE "pg_catalog"."default",
  "UserId" text COLLATE "pg_catalog"."default" NOT NULL
)
;

-- ----------------------------
-- Table structure for AspNetUserLogins
-- ----------------------------
DROP TABLE IF EXISTS "public"."AspNetUserLogins";
CREATE TABLE "public"."AspNetUserLogins" (
  "LoginProvider" text COLLATE "pg_catalog"."default" NOT NULL,
  "ProviderKey" text COLLATE "pg_catalog"."default" NOT NULL,
  "ProviderDisplayName" text COLLATE "pg_catalog"."default",
  "UserId" text COLLATE "pg_catalog"."default" NOT NULL
)
;

-- ----------------------------
-- Table structure for AspNetUserRoles
-- ----------------------------
DROP TABLE IF EXISTS "public"."AspNetUserRoles";
CREATE TABLE "public"."AspNetUserRoles" (
  "UserId" text COLLATE "pg_catalog"."default" NOT NULL,
  "RoleId" text COLLATE "pg_catalog"."default" NOT NULL
)
;

-- ----------------------------
-- Table structure for AspNetUserTokens
-- ----------------------------
DROP TABLE IF EXISTS "public"."AspNetUserTokens";
CREATE TABLE "public"."AspNetUserTokens" (
  "UserId" text COLLATE "pg_catalog"."default" NOT NULL,
  "LoginProvider" text COLLATE "pg_catalog"."default" NOT NULL,
  "Name" text COLLATE "pg_catalog"."default" NOT NULL,
  "Value" text COLLATE "pg_catalog"."default"
)
;

-- ----------------------------
-- Table structure for AspNetUsers
-- ----------------------------
DROP TABLE IF EXISTS "public"."AspNetUsers";
CREATE TABLE "public"."AspNetUsers" (
  "Id" text COLLATE "pg_catalog"."default" NOT NULL,
  "AccessFailedCount" int4 NOT NULL,
  "ConcurrencyStamp" text COLLATE "pg_catalog"."default",
  ) COLLATE "pg_catalog"."default",
  "EmailConfirmed" bool NOT NULL,
  "LockoutEnabled" bool NOT NULL,
  ),
  ) COLLATE "pg_catalog"."default",
  ) COLLATE "pg_catalog"."default",
  "PasswordHash" text COLLATE "pg_catalog"."default",
  "PhoneNumber" text COLLATE "pg_catalog"."default",
  "PhoneNumberConfirmed" bool NOT NULL,
  "SecurityStamp" text COLLATE "pg_catalog"."default",
  "TwoFactorEnabled" bool NOT NULL,
  ) COLLATE "pg_catalog"."default"
)
;

-- ----------------------------
-- Table structure for ClientClaims
-- ----------------------------
DROP TABLE IF EXISTS "public"."ClientClaims";
CREATE TABLE "public"."ClientClaims" (
  "Id" int4 NOT NULL DEFAULT nextval('"ClientClaims_Id_seq"'::regclass),
  "ClientId" int4 NOT NULL,
  ) COLLATE "pg_catalog"."default" NOT NULL,
  ) COLLATE "pg_catalog"."default" NOT NULL
)
;

-- ----------------------------
-- Table structure for ClientCorsOrigins
-- ----------------------------
DROP TABLE IF EXISTS "public"."ClientCorsOrigins";
CREATE TABLE "public"."ClientCorsOrigins" (
  "Id" int4 NOT NULL DEFAULT nextval('"ClientCorsOrigins_Id_seq"'::regclass),
  "ClientId" int4 NOT NULL,
  ) COLLATE "pg_catalog"."default" NOT NULL
)
;

-- ----------------------------
-- Table structure for ClientGrantTypes
-- ----------------------------
DROP TABLE IF EXISTS "public"."ClientGrantTypes";
CREATE TABLE "public"."ClientGrantTypes" (
  "Id" int4 NOT NULL DEFAULT nextval('"ClientGrantTypes_Id_seq"'::regclass),
  "ClientId" int4 NOT NULL,
  ) COLLATE "pg_catalog"."default" NOT NULL
)
;

-- ----------------------------
-- Table structure for ClientIdPRestrictions
-- ----------------------------
DROP TABLE IF EXISTS "public"."ClientIdPRestrictions";
CREATE TABLE "public"."ClientIdPRestrictions" (
  "Id" int4 NOT NULL DEFAULT nextval('"ClientIdPRestrictions_Id_seq"'::regclass),
  "ClientId" int4 NOT NULL,
  ) COLLATE "pg_catalog"."default" NOT NULL
)
;

-- ----------------------------
-- Table structure for ClientPostLogoutRedirectUris
-- ----------------------------
DROP TABLE IF EXISTS "public"."ClientPostLogoutRedirectUris";
CREATE TABLE "public"."ClientPostLogoutRedirectUris" (
  "Id" int4 NOT NULL DEFAULT nextval('"ClientPostLogoutRedirectUris_Id_seq"'::regclass),
  "ClientId" int4 NOT NULL,
  ) COLLATE "pg_catalog"."default" NOT NULL
)
;

-- ----------------------------
-- Table structure for ClientProperties
-- ----------------------------
DROP TABLE IF EXISTS "public"."ClientProperties";
CREATE TABLE "public"."ClientProperties" (
  "Id" int4 NOT NULL DEFAULT nextval('"ClientProperties_Id_seq"'::regclass),
  "ClientId" int4 NOT NULL,
  ) COLLATE "pg_catalog"."default" NOT NULL,
  ) COLLATE "pg_catalog"."default" NOT NULL
)
;

-- ----------------------------
-- Table structure for ClientRedirectUris
-- ----------------------------
DROP TABLE IF EXISTS "public"."ClientRedirectUris";
CREATE TABLE "public"."ClientRedirectUris" (
  "Id" int4 NOT NULL DEFAULT nextval('"ClientRedirectUris_Id_seq"'::regclass),
  "ClientId" int4 NOT NULL,
  ) COLLATE "pg_catalog"."default" NOT NULL
)
;

-- ----------------------------
-- Table structure for ClientScopes
-- ----------------------------
DROP TABLE IF EXISTS "public"."ClientScopes";
CREATE TABLE "public"."ClientScopes" (
  "Id" int4 NOT NULL DEFAULT nextval('"ClientScopes_Id_seq"'::regclass),
  "ClientId" int4 NOT NULL,
  ) COLLATE "pg_catalog"."default" NOT NULL
)
;

-- ----------------------------
-- Table structure for ClientSecrets
-- ----------------------------
DROP TABLE IF EXISTS "public"."ClientSecrets";
CREATE TABLE "public"."ClientSecrets" (
  "Id" int4 NOT NULL DEFAULT nextval('"ClientSecrets_Id_seq"'::regclass),
  "ClientId" int4 NOT NULL,
  ) COLLATE "pg_catalog"."default",
  ),
  ) COLLATE "pg_catalog"."default",
  ) COLLATE "pg_catalog"."default" NOT NULL
)
;

-- ----------------------------
-- Table structure for Clients
-- ----------------------------
DROP TABLE IF EXISTS "public"."Clients";
CREATE TABLE "public"."Clients" (
  "Id" int4 NOT NULL DEFAULT nextval('"Clients_Id_seq"'::regclass),
  "AbsoluteRefreshTokenLifetime" int4 NOT NULL,
  "AccessTokenLifetime" int4 NOT NULL,
  "AccessTokenType" int4 NOT NULL,
  "AllowAccessTokensViaBrowser" bool NOT NULL,
  "AllowOfflineAccess" bool NOT NULL,
  "AllowPlainTextPkce" bool NOT NULL,
  "AllowRememberConsent" bool NOT NULL,
  "AlwaysIncludeUserClaimsInIdToken" bool NOT NULL,
  "AlwaysSendClientClaims" bool NOT NULL,
  "AuthorizationCodeLifetime" int4 NOT NULL,
  "BackChannelLogoutSessionRequired" bool NOT NULL,
  ) COLLATE "pg_catalog"."default",
  ) COLLATE "pg_catalog"."default",
  ) COLLATE "pg_catalog"."default" NOT NULL,
  ) COLLATE "pg_catalog"."default",
  ) COLLATE "pg_catalog"."default",
  "ConsentLifetime" int4,
  ) COLLATE "pg_catalog"."default",
  "EnableLocalLogin" bool NOT NULL,
  "Enabled" bool NOT NULL,
  "FrontChannelLogoutSessionRequired" bool NOT NULL,
  ) COLLATE "pg_catalog"."default",
  "IdentityTokenLifetime" int4 NOT NULL,
  "IncludeJwtId" bool NOT NULL,
  ) COLLATE "pg_catalog"."default",
  ) COLLATE "pg_catalog"."default",
  ) COLLATE "pg_catalog"."default" NOT NULL,
  "RefreshTokenExpiration" int4 NOT NULL,
  "RefreshTokenUsage" int4 NOT NULL,
  "RequireClientSecret" bool NOT NULL,
  "RequireConsent" bool NOT NULL,
  "RequirePkce" bool NOT NULL,
  "SlidingRefreshTokenLifetime" int4 NOT NULL,
  "UpdateAccessTokenClaimsOnRefresh" bool NOT NULL
)
;

-- ----------------------------
-- Table structure for IdentityClaims
-- ----------------------------
DROP TABLE IF EXISTS "public"."IdentityClaims";
CREATE TABLE "public"."IdentityClaims" (
  "Id" int4 NOT NULL DEFAULT nextval('"IdentityClaims_Id_seq"'::regclass),
  "IdentityResourceId" int4 NOT NULL,
  ) COLLATE "pg_catalog"."default" NOT NULL
)
;

-- ----------------------------
-- Table structure for IdentityResources
-- ----------------------------
DROP TABLE IF EXISTS "public"."IdentityResources";
CREATE TABLE "public"."IdentityResources" (
  "Id" int4 NOT NULL DEFAULT nextval('"IdentityResources_Id_seq"'::regclass),
  ) COLLATE "pg_catalog"."default",
  ) COLLATE "pg_catalog"."default",
  "Emphasize" bool NOT NULL,
  "Enabled" bool NOT NULL,
  ) COLLATE "pg_catalog"."default" NOT NULL,
  "Required" bool NOT NULL,
  "ShowInDiscoveryDocument" bool NOT NULL
)
;

-- ----------------------------
-- Table structure for PersistedGrants
-- ----------------------------
DROP TABLE IF EXISTS "public"."PersistedGrants";
CREATE TABLE "public"."PersistedGrants" (
  ) COLLATE "pg_catalog"."default" NOT NULL,
  ) COLLATE "pg_catalog"."default" NOT NULL,
  ) NOT NULL,
  ) COLLATE "pg_catalog"."default" NOT NULL,
  ),
  ) COLLATE "pg_catalog"."default",
  ) COLLATE "pg_catalog"."default" NOT NULL
)
;

-- ----------------------------
-- Table structure for __EFMigrationsHistory
-- ----------------------------
DROP TABLE IF EXISTS "public"."__EFMigrationsHistory";
CREATE TABLE "public"."__EFMigrationsHistory" (
  ) COLLATE "pg_catalog"."default" NOT NULL,
  ) COLLATE "pg_catalog"."default" NOT NULL
)
;

-- ----------------------------
-- Alter sequences owned by
-- ----------------------------
ALTER SEQUENCE "public"."ApiClaims_Id_seq"
OWNED BY "public"."ApiClaims"."Id";
SELECT setval(, false);
ALTER SEQUENCE "public"."ApiResources_Id_seq"
OWNED BY "public"."ApiResources"."Id";
SELECT setval(, false);
ALTER SEQUENCE "public"."ApiScopeClaims_Id_seq"
OWNED BY "public"."ApiScopeClaims"."Id";
SELECT setval(, false);
ALTER SEQUENCE "public"."ApiScopes_Id_seq"
OWNED BY "public"."ApiScopes"."Id";
SELECT setval(, false);
ALTER SEQUENCE "public"."ApiSecrets_Id_seq"
OWNED BY "public"."ApiSecrets"."Id";
SELECT setval(, false);
ALTER SEQUENCE "public"."AspNetRoleClaims_Id_seq"
OWNED BY "public"."AspNetRoleClaims"."Id";
SELECT setval(, false);
ALTER SEQUENCE "public"."AspNetUserClaims_Id_seq"
OWNED BY "public"."AspNetUserClaims"."Id";
SELECT setval(, false);
ALTER SEQUENCE "public"."ClientClaims_Id_seq"
OWNED BY "public"."ClientClaims"."Id";
SELECT setval(, false);
ALTER SEQUENCE "public"."ClientCorsOrigins_Id_seq"
OWNED BY "public"."ClientCorsOrigins"."Id";
SELECT setval(, false);
ALTER SEQUENCE "public"."ClientGrantTypes_Id_seq"
OWNED BY "public"."ClientGrantTypes"."Id";
SELECT setval(, false);
ALTER SEQUENCE "public"."ClientIdPRestrictions_Id_seq"
OWNED BY "public"."ClientIdPRestrictions"."Id";
SELECT setval(, false);
ALTER SEQUENCE "public"."ClientPostLogoutRedirectUris_Id_seq"
OWNED BY "public"."ClientPostLogoutRedirectUris"."Id";
SELECT setval(, false);
ALTER SEQUENCE "public"."ClientProperties_Id_seq"
OWNED BY "public"."ClientProperties"."Id";
SELECT setval(, false);
ALTER SEQUENCE "public"."ClientRedirectUris_Id_seq"
OWNED BY "public"."ClientRedirectUris"."Id";
SELECT setval(, false);
ALTER SEQUENCE "public"."ClientScopes_Id_seq"
OWNED BY "public"."ClientScopes"."Id";
SELECT setval(, false);
ALTER SEQUENCE "public"."ClientSecrets_Id_seq"
OWNED BY "public"."ClientSecrets"."Id";
SELECT setval(, false);
ALTER SEQUENCE "public"."Clients_Id_seq"
OWNED BY "public"."Clients"."Id";
SELECT setval(, false);
ALTER SEQUENCE "public"."IdentityClaims_Id_seq"
OWNED BY "public"."IdentityClaims"."Id";
SELECT setval(, false);
ALTER SEQUENCE "public"."IdentityResources_Id_seq"
OWNED BY "public"."IdentityResources"."Id";
SELECT setval(, false);

-- ----------------------------
-- Indexes structure for table ApiClaims
-- ----------------------------
CREATE INDEX "IX_ApiClaims_ApiResourceId" ON "public"."ApiClaims" USING btree (
  "ApiResourceId" "pg_catalog"."int4_ops" ASC NULLS LAST
);

-- ----------------------------
-- Primary Key structure for table ApiClaims
-- ----------------------------
ALTER TABLE "public"."ApiClaims" ADD CONSTRAINT "PK_ApiClaims" PRIMARY KEY ("Id");

-- ----------------------------
-- Indexes structure for table ApiResources
-- ----------------------------
CREATE UNIQUE INDEX "IX_ApiResources_Name" ON "public"."ApiResources" USING btree (
  "Name" COLLATE "pg_catalog"."default" "pg_catalog"."text_ops" ASC NULLS LAST
);

-- ----------------------------
-- Primary Key structure for table ApiResources
-- ----------------------------
ALTER TABLE "public"."ApiResources" ADD CONSTRAINT "PK_ApiResources" PRIMARY KEY ("Id");

-- ----------------------------
-- Indexes structure for table ApiScopeClaims
-- ----------------------------
CREATE INDEX "IX_ApiScopeClaims_ApiScopeId" ON "public"."ApiScopeClaims" USING btree (
  "ApiScopeId" "pg_catalog"."int4_ops" ASC NULLS LAST
);

-- ----------------------------
-- Primary Key structure for table ApiScopeClaims
-- ----------------------------
ALTER TABLE "public"."ApiScopeClaims" ADD CONSTRAINT "PK_ApiScopeClaims" PRIMARY KEY ("Id");

-- ----------------------------
-- Indexes structure for table ApiScopes
-- ----------------------------
CREATE INDEX "IX_ApiScopes_ApiResourceId" ON "public"."ApiScopes" USING btree (
  "ApiResourceId" "pg_catalog"."int4_ops" ASC NULLS LAST
);
CREATE UNIQUE INDEX "IX_ApiScopes_Name" ON "public"."ApiScopes" USING btree (
  "Name" COLLATE "pg_catalog"."default" "pg_catalog"."text_ops" ASC NULLS LAST
);

-- ----------------------------
-- Primary Key structure for table ApiScopes
-- ----------------------------
ALTER TABLE "public"."ApiScopes" ADD CONSTRAINT "PK_ApiScopes" PRIMARY KEY ("Id");

-- ----------------------------
-- Indexes structure for table ApiSecrets
-- ----------------------------
CREATE INDEX "IX_ApiSecrets_ApiResourceId" ON "public"."ApiSecrets" USING btree (
  "ApiResourceId" "pg_catalog"."int4_ops" ASC NULLS LAST
);

-- ----------------------------
-- Primary Key structure for table ApiSecrets
-- ----------------------------
ALTER TABLE "public"."ApiSecrets" ADD CONSTRAINT "PK_ApiSecrets" PRIMARY KEY ("Id");

-- ----------------------------
-- Indexes structure for table AspNetRoleClaims
-- ----------------------------
CREATE INDEX "IX_AspNetRoleClaims_RoleId" ON "public"."AspNetRoleClaims" USING btree (
  "RoleId" COLLATE "pg_catalog"."default" "pg_catalog"."text_ops" ASC NULLS LAST
);

-- ----------------------------
-- Primary Key structure for table AspNetRoleClaims
-- ----------------------------
ALTER TABLE "public"."AspNetRoleClaims" ADD CONSTRAINT "PK_AspNetRoleClaims" PRIMARY KEY ("Id");

-- ----------------------------
-- Indexes structure for table AspNetRoles
-- ----------------------------
CREATE UNIQUE INDEX "RoleNameIndex" ON "public"."AspNetRoles" USING btree (
  "NormalizedName" COLLATE "pg_catalog"."default" "pg_catalog"."text_ops" ASC NULLS LAST
);

-- ----------------------------
-- Primary Key structure for table AspNetRoles
-- ----------------------------
ALTER TABLE "public"."AspNetRoles" ADD CONSTRAINT "PK_AspNetRoles" PRIMARY KEY ("Id");

-- ----------------------------
-- Indexes structure for table AspNetUserClaims
-- ----------------------------
CREATE INDEX "IX_AspNetUserClaims_UserId" ON "public"."AspNetUserClaims" USING btree (
  "UserId" COLLATE "pg_catalog"."default" "pg_catalog"."text_ops" ASC NULLS LAST
);

-- ----------------------------
-- Primary Key structure for table AspNetUserClaims
-- ----------------------------
ALTER TABLE "public"."AspNetUserClaims" ADD CONSTRAINT "PK_AspNetUserClaims" PRIMARY KEY ("Id");

-- ----------------------------
-- Indexes structure for table AspNetUserLogins
-- ----------------------------
CREATE INDEX "IX_AspNetUserLogins_UserId" ON "public"."AspNetUserLogins" USING btree (
  "UserId" COLLATE "pg_catalog"."default" "pg_catalog"."text_ops" ASC NULLS LAST
);

-- ----------------------------
-- Primary Key structure for table AspNetUserLogins
-- ----------------------------
ALTER TABLE "public"."AspNetUserLogins" ADD CONSTRAINT "PK_AspNetUserLogins" PRIMARY KEY ("LoginProvider", "ProviderKey");

-- ----------------------------
-- Indexes structure for table AspNetUserRoles
-- ----------------------------
CREATE INDEX "IX_AspNetUserRoles_RoleId" ON "public"."AspNetUserRoles" USING btree (
  "RoleId" COLLATE "pg_catalog"."default" "pg_catalog"."text_ops" ASC NULLS LAST
);

-- ----------------------------
-- Primary Key structure for table AspNetUserRoles
-- ----------------------------
ALTER TABLE "public"."AspNetUserRoles" ADD CONSTRAINT "PK_AspNetUserRoles" PRIMARY KEY ("UserId", "RoleId");

-- ----------------------------
-- Primary Key structure for table AspNetUserTokens
-- ----------------------------
ALTER TABLE "public"."AspNetUserTokens" ADD CONSTRAINT "PK_AspNetUserTokens" PRIMARY KEY ("UserId", "LoginProvider", "Name");

-- ----------------------------
-- Indexes structure for table AspNetUsers
-- ----------------------------
CREATE INDEX "EmailIndex" ON "public"."AspNetUsers" USING btree (
  "NormalizedEmail" COLLATE "pg_catalog"."default" "pg_catalog"."text_ops" ASC NULLS LAST
);
CREATE UNIQUE INDEX "UserNameIndex" ON "public"."AspNetUsers" USING btree (
  "NormalizedUserName" COLLATE "pg_catalog"."default" "pg_catalog"."text_ops" ASC NULLS LAST
);

-- ----------------------------
-- Primary Key structure for table AspNetUsers
-- ----------------------------
ALTER TABLE "public"."AspNetUsers" ADD CONSTRAINT "PK_AspNetUsers" PRIMARY KEY ("Id");

-- ----------------------------
-- Indexes structure for table ClientClaims
-- ----------------------------
CREATE INDEX "IX_ClientClaims_ClientId" ON "public"."ClientClaims" USING btree (
  "ClientId" "pg_catalog"."int4_ops" ASC NULLS LAST
);

-- ----------------------------
-- Primary Key structure for table ClientClaims
-- ----------------------------
ALTER TABLE "public"."ClientClaims" ADD CONSTRAINT "PK_ClientClaims" PRIMARY KEY ("Id");

-- ----------------------------
-- Indexes structure for table ClientCorsOrigins
-- ----------------------------
CREATE INDEX "IX_ClientCorsOrigins_ClientId" ON "public"."ClientCorsOrigins" USING btree (
  "ClientId" "pg_catalog"."int4_ops" ASC NULLS LAST
);

-- ----------------------------
-- Primary Key structure for table ClientCorsOrigins
-- ----------------------------
ALTER TABLE "public"."ClientCorsOrigins" ADD CONSTRAINT "PK_ClientCorsOrigins" PRIMARY KEY ("Id");

-- ----------------------------
-- Indexes structure for table ClientGrantTypes
-- ----------------------------
CREATE INDEX "IX_ClientGrantTypes_ClientId" ON "public"."ClientGrantTypes" USING btree (
  "ClientId" "pg_catalog"."int4_ops" ASC NULLS LAST
);

-- ----------------------------
-- Primary Key structure for table ClientGrantTypes
-- ----------------------------
ALTER TABLE "public"."ClientGrantTypes" ADD CONSTRAINT "PK_ClientGrantTypes" PRIMARY KEY ("Id");

-- ----------------------------
-- Indexes structure for table ClientIdPRestrictions
-- ----------------------------
CREATE INDEX "IX_ClientIdPRestrictions_ClientId" ON "public"."ClientIdPRestrictions" USING btree (
  "ClientId" "pg_catalog"."int4_ops" ASC NULLS LAST
);

-- ----------------------------
-- Primary Key structure for table ClientIdPRestrictions
-- ----------------------------
ALTER TABLE "public"."ClientIdPRestrictions" ADD CONSTRAINT "PK_ClientIdPRestrictions" PRIMARY KEY ("Id");

-- ----------------------------
-- Indexes structure for table ClientPostLogoutRedirectUris
-- ----------------------------
CREATE INDEX "IX_ClientPostLogoutRedirectUris_ClientId" ON "public"."ClientPostLogoutRedirectUris" USING btree (
  "ClientId" "pg_catalog"."int4_ops" ASC NULLS LAST
);

-- ----------------------------
-- Primary Key structure for table ClientPostLogoutRedirectUris
-- ----------------------------
ALTER TABLE "public"."ClientPostLogoutRedirectUris" ADD CONSTRAINT "PK_ClientPostLogoutRedirectUris" PRIMARY KEY ("Id");

-- ----------------------------
-- Indexes structure for table ClientProperties
-- ----------------------------
CREATE INDEX "IX_ClientProperties_ClientId" ON "public"."ClientProperties" USING btree (
  "ClientId" "pg_catalog"."int4_ops" ASC NULLS LAST
);

-- ----------------------------
-- Primary Key structure for table ClientProperties
-- ----------------------------
ALTER TABLE "public"."ClientProperties" ADD CONSTRAINT "PK_ClientProperties" PRIMARY KEY ("Id");

-- ----------------------------
-- Indexes structure for table ClientRedirectUris
-- ----------------------------
CREATE INDEX "IX_ClientRedirectUris_ClientId" ON "public"."ClientRedirectUris" USING btree (
  "ClientId" "pg_catalog"."int4_ops" ASC NULLS LAST
);

-- ----------------------------
-- Primary Key structure for table ClientRedirectUris
-- ----------------------------
ALTER TABLE "public"."ClientRedirectUris" ADD CONSTRAINT "PK_ClientRedirectUris" PRIMARY KEY ("Id");

-- ----------------------------
-- Indexes structure for table ClientScopes
-- ----------------------------
CREATE INDEX "IX_ClientScopes_ClientId" ON "public"."ClientScopes" USING btree (
  "ClientId" "pg_catalog"."int4_ops" ASC NULLS LAST
);

-- ----------------------------
-- Primary Key structure for table ClientScopes
-- ----------------------------
ALTER TABLE "public"."ClientScopes" ADD CONSTRAINT "PK_ClientScopes" PRIMARY KEY ("Id");

-- ----------------------------
-- Indexes structure for table ClientSecrets
-- ----------------------------
CREATE INDEX "IX_ClientSecrets_ClientId" ON "public"."ClientSecrets" USING btree (
  "ClientId" "pg_catalog"."int4_ops" ASC NULLS LAST
);

-- ----------------------------
-- Primary Key structure for table ClientSecrets
-- ----------------------------
ALTER TABLE "public"."ClientSecrets" ADD CONSTRAINT "PK_ClientSecrets" PRIMARY KEY ("Id");

-- ----------------------------
-- Indexes structure for table Clients
-- ----------------------------
CREATE UNIQUE INDEX "IX_Clients_ClientId" ON "public"."Clients" USING btree (
  "ClientId" COLLATE "pg_catalog"."default" "pg_catalog"."text_ops" ASC NULLS LAST
);

-- ----------------------------
-- Primary Key structure for table Clients
-- ----------------------------
ALTER TABLE "public"."Clients" ADD CONSTRAINT "PK_Clients" PRIMARY KEY ("Id");

-- ----------------------------
-- Indexes structure for table IdentityClaims
-- ----------------------------
CREATE INDEX "IX_IdentityClaims_IdentityResourceId" ON "public"."IdentityClaims" USING btree (
  "IdentityResourceId" "pg_catalog"."int4_ops" ASC NULLS LAST
);

-- ----------------------------
-- Primary Key structure for table IdentityClaims
-- ----------------------------
ALTER TABLE "public"."IdentityClaims" ADD CONSTRAINT "PK_IdentityClaims" PRIMARY KEY ("Id");

-- ----------------------------
-- Indexes structure for table IdentityResources
-- ----------------------------
CREATE UNIQUE INDEX "IX_IdentityResources_Name" ON "public"."IdentityResources" USING btree (
  "Name" COLLATE "pg_catalog"."default" "pg_catalog"."text_ops" ASC NULLS LAST
);

-- ----------------------------
-- Primary Key structure for table IdentityResources
-- ----------------------------
ALTER TABLE "public"."IdentityResources" ADD CONSTRAINT "PK_IdentityResources" PRIMARY KEY ("Id");

-- ----------------------------
-- Indexes structure for table PersistedGrants
-- ----------------------------
CREATE INDEX "IX_PersistedGrants_SubjectId_ClientId_Type" ON "public"."PersistedGrants" USING btree (
  "SubjectId" COLLATE "pg_catalog"."default" "pg_catalog"."text_ops" ASC NULLS LAST,
  "ClientId" COLLATE "pg_catalog"."default" "pg_catalog"."text_ops" ASC NULLS LAST,
  "Type" COLLATE "pg_catalog"."default" "pg_catalog"."text_ops" ASC NULLS LAST
);

-- ----------------------------
-- Primary Key structure for table PersistedGrants
-- ----------------------------
ALTER TABLE "public"."PersistedGrants" ADD CONSTRAINT "PK_PersistedGrants" PRIMARY KEY ("Key");

-- ----------------------------
-- Primary Key structure for table __EFMigrationsHistory
-- ----------------------------
ALTER TABLE "public"."__EFMigrationsHistory" ADD CONSTRAINT "PK___EFMigrationsHistory" PRIMARY KEY ("MigrationId");

-- ----------------------------
-- Foreign Keys structure for table ApiClaims
-- ----------------------------
ALTER TABLE "public"."ApiClaims" ADD CONSTRAINT "FK_ApiClaims_ApiResources_ApiResourceId" FOREIGN KEY ("ApiResourceId") REFERENCES "ApiResources" ("Id") ON DELETE CASCADE ON UPDATE NO ACTION;

-- ----------------------------
-- Foreign Keys structure for table ApiScopeClaims
-- ----------------------------
ALTER TABLE "public"."ApiScopeClaims" ADD CONSTRAINT "FK_ApiScopeClaims_ApiScopes_ApiScopeId" FOREIGN KEY ("ApiScopeId") REFERENCES "ApiScopes" ("Id") ON DELETE CASCADE ON UPDATE NO ACTION;

-- ----------------------------
-- Foreign Keys structure for table ApiScopes
-- ----------------------------
ALTER TABLE "public"."ApiScopes" ADD CONSTRAINT "FK_ApiScopes_ApiResources_ApiResourceId" FOREIGN KEY ("ApiResourceId") REFERENCES "ApiResources" ("Id") ON DELETE CASCADE ON UPDATE NO ACTION;

-- ----------------------------
-- Foreign Keys structure for table ApiSecrets
-- ----------------------------
ALTER TABLE "public"."ApiSecrets" ADD CONSTRAINT "FK_ApiSecrets_ApiResources_ApiResourceId" FOREIGN KEY ("ApiResourceId") REFERENCES "ApiResources" ("Id") ON DELETE CASCADE ON UPDATE NO ACTION;

-- ----------------------------
-- Foreign Keys structure for table AspNetRoleClaims
-- ----------------------------
ALTER TABLE "public"."AspNetRoleClaims" ADD CONSTRAINT "FK_AspNetRoleClaims_AspNetRoles_RoleId" FOREIGN KEY ("RoleId") REFERENCES "AspNetRoles" ("Id") ON DELETE CASCADE ON UPDATE NO ACTION;

-- ----------------------------
-- Foreign Keys structure for table AspNetUserClaims
-- ----------------------------
ALTER TABLE "public"."AspNetUserClaims" ADD CONSTRAINT "FK_AspNetUserClaims_AspNetUsers_UserId" FOREIGN KEY ("UserId") REFERENCES "AspNetUsers" ("Id") ON DELETE CASCADE ON UPDATE NO ACTION;

-- ----------------------------
-- Foreign Keys structure for table AspNetUserLogins
-- ----------------------------
ALTER TABLE "public"."AspNetUserLogins" ADD CONSTRAINT "FK_AspNetUserLogins_AspNetUsers_UserId" FOREIGN KEY ("UserId") REFERENCES "AspNetUsers" ("Id") ON DELETE CASCADE ON UPDATE NO ACTION;

-- ----------------------------
-- Foreign Keys structure for table AspNetUserRoles
-- ----------------------------
ALTER TABLE "public"."AspNetUserRoles" ADD CONSTRAINT "FK_AspNetUserRoles_AspNetRoles_RoleId" FOREIGN KEY ("RoleId") REFERENCES "AspNetRoles" ("Id") ON DELETE CASCADE ON UPDATE NO ACTION;
ALTER TABLE "public"."AspNetUserRoles" ADD CONSTRAINT "FK_AspNetUserRoles_AspNetUsers_UserId" FOREIGN KEY ("UserId") REFERENCES "AspNetUsers" ("Id") ON DELETE CASCADE ON UPDATE NO ACTION;

-- ----------------------------
-- Foreign Keys structure for table AspNetUserTokens
-- ----------------------------
ALTER TABLE "public"."AspNetUserTokens" ADD CONSTRAINT "FK_AspNetUserTokens_AspNetUsers_UserId" FOREIGN KEY ("UserId") REFERENCES "AspNetUsers" ("Id") ON DELETE CASCADE ON UPDATE NO ACTION;

-- ----------------------------
-- Foreign Keys structure for table ClientClaims
-- ----------------------------
ALTER TABLE "public"."ClientClaims" ADD CONSTRAINT "FK_ClientClaims_Clients_ClientId" FOREIGN KEY ("ClientId") REFERENCES "Clients" ("Id") ON DELETE CASCADE ON UPDATE NO ACTION;

-- ----------------------------
-- Foreign Keys structure for table ClientCorsOrigins
-- ----------------------------
ALTER TABLE "public"."ClientCorsOrigins" ADD CONSTRAINT "FK_ClientCorsOrigins_Clients_ClientId" FOREIGN KEY ("ClientId") REFERENCES "Clients" ("Id") ON DELETE CASCADE ON UPDATE NO ACTION;

-- ----------------------------
-- Foreign Keys structure for table ClientGrantTypes
-- ----------------------------
ALTER TABLE "public"."ClientGrantTypes" ADD CONSTRAINT "FK_ClientGrantTypes_Clients_ClientId" FOREIGN KEY ("ClientId") REFERENCES "Clients" ("Id") ON DELETE CASCADE ON UPDATE NO ACTION;

-- ----------------------------
-- Foreign Keys structure for table ClientIdPRestrictions
-- ----------------------------
ALTER TABLE "public"."ClientIdPRestrictions" ADD CONSTRAINT "FK_ClientIdPRestrictions_Clients_ClientId" FOREIGN KEY ("ClientId") REFERENCES "Clients" ("Id") ON DELETE CASCADE ON UPDATE NO ACTION;

-- ----------------------------
-- Foreign Keys structure for table ClientPostLogoutRedirectUris
-- ----------------------------
ALTER TABLE "public"."ClientPostLogoutRedirectUris" ADD CONSTRAINT "FK_ClientPostLogoutRedirectUris_Clients_ClientId" FOREIGN KEY ("ClientId") REFERENCES "Clients" ("Id") ON DELETE CASCADE ON UPDATE NO ACTION;

-- ----------------------------
-- Foreign Keys structure for table ClientProperties
-- ----------------------------
ALTER TABLE "public"."ClientProperties" ADD CONSTRAINT "FK_ClientProperties_Clients_ClientId" FOREIGN KEY ("ClientId") REFERENCES "Clients" ("Id") ON DELETE CASCADE ON UPDATE NO ACTION;

-- ----------------------------
-- Foreign Keys structure for table ClientRedirectUris
-- ----------------------------
ALTER TABLE "public"."ClientRedirectUris" ADD CONSTRAINT "FK_ClientRedirectUris_Clients_ClientId" FOREIGN KEY ("ClientId") REFERENCES "Clients" ("Id") ON DELETE CASCADE ON UPDATE NO ACTION;

-- ----------------------------
-- Foreign Keys structure for table ClientScopes
-- ----------------------------
ALTER TABLE "public"."ClientScopes" ADD CONSTRAINT "FK_ClientScopes_Clients_ClientId" FOREIGN KEY ("ClientId") REFERENCES "Clients" ("Id") ON DELETE CASCADE ON UPDATE NO ACTION;

-- ----------------------------
-- Foreign Keys structure for table ClientSecrets
-- ----------------------------
ALTER TABLE "public"."ClientSecrets" ADD CONSTRAINT "FK_ClientSecrets_Clients_ClientId" FOREIGN KEY ("ClientId") REFERENCES "Clients" ("Id") ON DELETE CASCADE ON UPDATE NO ACTION;

-- ----------------------------
-- Foreign Keys structure for table IdentityClaims
-- ----------------------------
ALTER TABLE "public"."IdentityClaims" ADD CONSTRAINT "FK_IdentityClaims_IdentityResources_IdentityResourceId" FOREIGN KEY ("IdentityResourceId") REFERENCES "IdentityResources" ("Id") ON DELETE CASCADE ON UPDATE NO ACTION;

下面分析下初始化生成的数据

public static IEnumerable<IdentityResource> GetIdentityResources()
        {
            return new List<IdentityResource>
            {
                new IdentityResources.OpenId(),
                new IdentityResources.Profile(),
            };
        }

这里定义了两个IdentityResource,对应表IdentityResources

关联IdentityClaims

再看定义的API

public static IEnumerable<ApiResource> GetApiResources()
        {
            return new List<ApiResource>
            {
                new ApiResource("api1", "My API")
            };
        }

对应表ApiResources

以及ApiScopes

最后看定义的Client

public static IEnumerable<Client> GetClients()
        {
            return new List<Client>
            {
                new Client
                {
                    ClientId = "client",

                    // no interactive user, use the clientid/secret for authentication
                    AllowedGrantTypes = GrantTypes.ClientCredentials,

                    // secret for authentication
                    ClientSecrets =
                    {
                        new Secret("secret".Sha256())
                    },

                    // scopes that client has access to
                    AllowedScopes = { "api1" }
                },
                // resource owner password grant client
                new Client
                {
                    ClientId = "ro.client",
                    AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,

                    ClientSecrets =
                    {
                        new Secret("secret".Sha256())
                    },
                    AllowedScopes = { "api1" }
                },
                // OpenID Connect implicit flow client (MVC)
                new Client
                {
                    ClientId = "mvc",
                    ClientName = "MVC Client",
                    AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,

                    RequireConsent = false,

                    ClientSecrets =
                    {
                        new Secret("secret".Sha256())
                    },

                    RedirectUris           = { "http://localhost:5002/signin-oidc" },
                    PostLogoutRedirectUris = { "http://localhost:5002/signout-callback-oidc" },

                    AllowedScopes =
                    {
                        IdentityServerConstants.StandardScopes.OpenId,
                        IdentityServerConstants.StandardScopes.Profile,
                        "api1"
                    },
                    AllowOfflineAccess = true
                }
            };
        }

这里定义了三种不同授权方式的Client

先看表Clients

ClientScopes

ClientSecrets

ClientGrantTypes

ClientPostLogoutRedirectUris

ClientRedirectUris

在真实项目中就不用测试数据了,注释Configure里的InitializeDatabase(app);

ConfigureServices里面添加

services.AddDbContext<ConfigurationDbContext>(options =>
                options.UseMySQL(connectionString));

新建一个ClientController来创建Client

public class ClientController : Controller
    {
        private readonly ConfigurationDbContext _context;

        public ClientController(ConfigurationDbContext context)
        {
            this._context = context;
        }
        // GET: Client
        public async Task<IActionResult> Index()
        {
            return View(await _context.Clients.ToListAsync());
        }

        // GET: Client/Create
        public ActionResult Create()
        {
            return View();
        }

        // POST: Client/Create
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create(IFormCollection collection)
        {
            try
            {
                // TODO: Add insert logic here
                string clientId = collection["ClientId"];
                string secret = collection["ClientSTecret"];
                string tokenTime = collection["TokenTime"];
                ;
                int.TryParse(tokenTime, out accessTokenLifetime);
                var client = new Client
                {
                    ClientId = clientId,

                    // no interactive user, use the clientid/secret for authentication
                    AllowedGrantTypes = GrantTypes.ClientCredentials,

                    // secret for authentication
                    ClientSecrets =
                    {
                        new Secret(secret.Sha256())
                    },
                    AccessTokenLifetime= accessTokenLifetime,//设置过期时间,默认3600秒/1小时
                    // scopes that client has access to
                    AllowedScopes = {  }
                };
                _context.Clients.Add(client.ToEntity());
                _context.SaveChanges();
                return RedirectToAction(nameof(Index));
            }
            catch
            {
                return View();
            }
        }

    }

Index.cshtml

@model IEnumerable<IdentityServer4.EntityFramework.Entities.Client>
@{
    ViewData["Title"] = "Index";
}

<h2>Index</h2>

<p>
    <a asp-action="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>

            <th>
                @Html.DisplayNameFor(model => model.AccessTokenLifetime)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.ClientId)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.ClientName)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.ClientUri)
            </th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model)
        {
            <tr>

                <td>
                    @Html.DisplayFor(modelItem => item.AccessTokenLifetime)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.ClientId)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.ClientName)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.ClientUri)
                </td>
            </tr>
        }
    </tbody>
</table>

Create.cshtml

@{
    ViewData["Title"] = "Create";
}

<h2>Create</h2>

<h4>Clients</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Create">
            <div class="form-group">
                <label class="control-label">ClientId</label>
                <input name="ClientId" class="form-control" />
            </div>
            <div class="form-group">
                <label class="control-label">ClientSecret</label>
                <input name="ClientSecret" class="form-control" />
            </div>
            <div class="form-group">
                <label class="control-label">TokenTime</label>
                <input name="TokenTime" class="form-control" />
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-action="Index">Back to List</a>
</div>

ApiResources和IdentityResources也可以用同样的方式添加。

可以使用Postman来请求token

部署HTTPS

修改program代码

.UseKestrel(options=> {
                    options.Listen(IPAddress.Any, , listenOptions =>
                    {
                        listenOptions.UseHttps("server.pfx", "test");
                    });
                })

这里的自签名证书可使用openssl生成

使用程序获取token

static void Main(string[] args)
        {
            //GetEndpoints();
            string url = "https://localhost/connect/token";
            using (HttpClient client = new HttpClient())
            {
                ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
                StringContent content = new StringContent("client_id=client&client_secret=secret&grant_type=client_credentials", Encoding.UTF8, "application/x-www-form-urlencoded");
                var response = client.PostAsync(url,content);
                Console.WriteLine(response.Result.Content.ReadAsStringAsync().Result);
            }
            Console.ReadKey();
        }

使用postman测试,需要在File--Settings里面取消ssl验证

IdentityServer-Protecting an API using Client Credentials的更多相关文章

  1. 利用Fiddler模拟通过Dynamics 365的OAuth 2 Client Credentials认证后调用Web API

    微软动态CRM专家罗勇 ,回复337或者20190521可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me. 配置Dynamics 365 & PowerApps 支 ...

  2. 基于 IdentityServer3 实现 OAuth 2.0 授权服务【客户端模式(Client Credentials Grant)】

    github:https://github.com/IdentityServer/IdentityServer3/ documentation:https://identityserver.githu ...

  3. IdentityServer4专题之五:OpenID Connect及其Client Credentials流程模式

    1.基于概念 OAuth2.0与身份认证协议的角色映射 OpenID Connect 这个协议是2014颁发的,基于OAuth2.0,在这个协议中,ID Token会和Access Token一起发回 ...

  4. IdentityServer4 (1) 客户端授权模式(Client Credentials)

    写在前面 1.源码(.Net Core 2.2) git地址:https://github.com/yizhaoxian/CoreIdentityServer4Demo.git 2.相关章节 2.1. ...

  5. 在ASP.NET中基于Owin OAuth使用Client Credentials Grant授权发放Token

    OAuth真是一个复杂的东东,即使你把OAuth规范倒背如流,在具体实现时也会无从下手.因此,Microsoft.Owin.Security.OAuth应运而生(它的实现代码在Katana项目中),帮 ...

  6. [OAuth]基于DotNetOpenAuth实现Client Credentials Grant

    Client Credentials Grant是指直接由Client向Authorization Server请求access token,无需用户(Resource Owner)的授权.比如我们提 ...

  7. (转)基于OWIN WebAPI 使用OAuth授权服务【客户端模式(Client Credentials Grant)】

    适应范围 采用Client Credentials方式,即应用公钥.密钥方式获取Access Token,适用于任何类型应用,但通过它所获取的Access Token只能用于访问与用户无关的Open ...

  8. 基于OWIN WebAPI 使用OAuth授权服务【客户端模式(Client Credentials Grant)】

    适应范围 采用Client Credentials方式,即应用公钥.密钥方式获取Access Token,适用于任何类型应用,但通过它所获取的Access Token只能用于访问与用户无关的Open ...

  9. 实现Client Credentials Grant

    [OAuth]基于DotNetOpenAuth实现Client Credentials Grant   Client Credentials Grant是指直接由Client向Authorizatio ...

随机推荐

  1. silverlight 父窗体传值给ChildWindow

    在网上找了许多列子,有的没有看懂,有的太麻烦. 现在有两种方法又简单又实用的,分享给大家! 第一种:使用构造函数传值 1.子页面新建一个构造函数 public ChildWindowTest(stri ...

  2. Ng第十六课:推荐系统(Recommender Systems)

    16.1  问题形式化 16.2  基于内容的推荐系统 16.3  协同过滤 16.4  协同过滤算法 16.5  矢量化:低秩矩阵分解 16.6  推行工作上的细节:均值归一化 16.1  问题形式 ...

  3. (多线程dp)Matrix (hdu 2686)

    http://acm.hdu.edu.cn/showproblem.php?pid=2686     Problem Description Yifenfei very like play a num ...

  4. kepware http接口 java语言开发

    读取某变量的值(OK HTTP OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder() .u ...

  5. 关于QT建立项目中遇到的相关问题的处理办法

    关于QT建立项目中遇到的相关问题的处理办法 1.在QTCreater中新建一个空的工程时,第一次运行会抱一个错误,如下: -1: error: LNK1123: 转换到 COFF 期间失败: 文件无效 ...

  6. hdu 4902 线段树+逆向模拟

    http://acm.hdu.edu.cn/showproblem.php?pid=4902 出n个数,然后对这n个数进行两种操作: 如果是 1 l r x,则把 [l, r] 区间里面的每一个数都变 ...

  7. CMUSphinx Learn - Before you start

    Before you start 开始之前 Before you start the development of the speech application, you need to consid ...

  8. debian7(wheezy)升级安装mercurial hg最新版2.8-RC,解决tortoisehg2.9.2不能使用。

    debian&(wheezy)之前的仓库版本是2.2.2.  注: 本文以 # 为开始的行是工作在root下的模式,在终端显示为root的提示符# ,用户目录的($:)需要切换到root(使用 ...

  9. 前端开发 - JavaScript

    本节内容 一.如何编写 二.变量 三.数据类型 四.其他 五.语句与异常 六.函数 JavaScript是一门编程语言,浏览器内置了JavaScript语言的解释器,所以在浏览器上按照JavaScri ...

  10. centos下添加git

    CentOS中yum里没有Git,需要手动安装. 首先需要安装git的依赖包 yum install curl yum install curl-devel yum install zlib-deve ...