首页 > 其他分享 >IdentityServer4入门

IdentityServer4入门

时间:2023-01-19 10:05:05浏览次数:53  
标签:Web 入门 C# simple client https new IdentityServer4


IdentifyServer项目

IdentityServer4是用于ASP.NET Core的OpenID Connect和OAuth 2.0框架。

官网:​​https://identityserver4.readthedocs.io/en/latest/​

  1. 创建Asp.net Web Core 空 模板项目,可以将基命名为:IdentityServer(名称可以随意,一般都取这个),注意必须配置Https
  2. 引用IdentityServer4
  3. 配置Config,必须是static 类
/// <summary>
/// IdentityServer4配置类
/// </summary>
public static class Config
{
/// <summary>
/// Api范围
/// </summary>
public static IEnumerable<ApiScope> ApiScopes => new[]
{
new ApiScope()
{
Name = "simple_api",
DisplayName = "Simple_API"
}
};

public static IEnumerable<Client> Clients => new[]
{
new Client()
{
ClientId = "simple_client",
ClientSecrets = new List<Secret>()
{
new Secret("simple_client_secret".Sha256())
},
AllowedGrantTypes = new List<string>(){GrantType.ClientCredentials},
AllowedScopes = { "simple_api" }//允许访问的api,可以有多个
},
//资源拥有者客户端
new Client()
{
ClientId = "simple_pass_client",
ClientSecrets = new List<Secret>()
{
new Secret("simple_client_secret".Sha256())
},
AllowedGrantTypes = new List<string>(){GrantType.ResourceOwnerPassword},
AllowedScopes = { "simple_api" }//允许访问的api,可以有多个
},

//配置OICD 重定向
new Client()
{
ClientId = "simple_mvc_client",
ClientName = "Simple Mvc Client",
ClientSecrets = new List<Secret>()
{
new Secret("simple_client_secret".Sha256())
},
AllowedGrantTypes = new List<string>(){GrantType.AuthorizationCode}, //授权码许可协议

//登录成功的跳转地址(坑点:必须使用Https!!!)
RedirectUris = {"https://localhost:4001/signin-oidc"}, //mvc客户端的地址,signin-oidc:标准协议里的端点名称
//登出后的跳转地址
PostLogoutRedirectUris = {"https://localhost:4001/signout-callback-oidc"},
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile, //IdentityResources中定义了这两项,在这里也需要声明
"simple_api"
},//允许访问的api,可以有多个
RequireConsent = true //是否需要用户点同意
},
};
//资源拥有者(TestUser只是IdentifyServer4提供的一个测试用户)
public static List<TestUser> Users = new List<TestUser>()
{
new TestUser()
{
SubjectId = "1",
Username = "admin",
Password = "123"
}
};
//定义身份资源(标准的oidc(OpenId Connect))
public static IEnumerable<IdentityResource> IdentityResources = new List<IdentityResource>()
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),//档案信息(昵称,头像。。。)
};
}
  1. 在​​StartUp.cs​​​ 中的​​ConfigureServices​​ 方法中配置如下:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();

services.AddIdentityServer()
.AddDeveloperSigningCredential() //默认的生成的密钥(运行后,会在项目根目录下生成文件 tempkey.jwk)
.AddInMemoryClients(Config.Clients) //注册客户端
.AddInMemoryApiScopes(Config.ApiScopes) //注册api访问范围
.AddTestUsers(Config.Users) //注册资源拥有者
.AddInMemoryIdentityResources(Config.IdentityResources); //用户的身份资源信息(例如:显示昵称,头像,等等信息)
}
  1. 在​​StartUp.cs​​​ 中的 ​​Configure​​ 配置如下代码
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}

app.UseStaticFiles();
app.UseRouting();
app.UseIdentityServer();
app.UseAuthorization();
app.UseEndpoints(endpoint =>
{
endpoint.MapDefaultControllerRoute();
});
}
  1. 运行测试地址:https://localhost:5000/.well-known/openid-configuration
{
"issuer": "https://localhost:5000",
"jwks_uri": "https://localhost:5000/.well-known/openid-configuration/jwks",
"authorization_endpoint": "https://localhost:5000/connect/authorize",
"token_endpoint": "https://localhost:5000/connect/token",
"userinfo_endpoint": "https://localhost:5000/connect/userinfo",
"end_session_endpoint": "https://localhost:5000/connect/endsession",
"check_session_iframe": "https://localhost:5000/connect/checksession",
"revocation_endpoint": "https://localhost:5000/connect/revocation",
"introspection_endpoint": "https://localhost:5000/connect/introspect",
"device_authorization_endpoint": "https://localhost:5000/connect/deviceauthorization",
"frontchannel_logout_supported": true,
"frontchannel_logout_session_supported": true,
"backchannel_logout_supported": true,
"backchannel_logout_session_supported": true,
"scopes_supported": [
"simple_api",
"offline_access"
],
"claims_supported": [],
"grant_types_supported": [
"authorization_code",
"client_credentials",
"refresh_token",
"implicit",
"urn:ietf:params:oauth:grant-type:device_code"
],
"response_types_supported": [
"code",
"token",
"id_token",
"id_token token",
"code id_token",
"code token",
"code id_token token"
],
"response_modes_supported": [
"form_post",
"query",
"fragment"
],
"token_endpoint_auth_methods_supported": [
"client_secret_basic",
"client_secret_post"
],
"id_token_signing_alg_values_supported": [
"RS256"
],
"subject_types_supported": [
"public"
],
"code_challenge_methods_supported": [
"plain",
"S256"
],
"request_parameter_supported": true
}

5.测试client : Post 请求 https://localhost:5000/connect/token,传递请求参数:

  • 测试 客户端1(simple_client)
    client_id:simple_client
    client_secret:simple_client_secret
    grant_type:client_credentials
{
"access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjlBMjVFQUVFMjI4RDQyOUQ0QzFEMTc1NjNENzJEQTgzIiwidHlwIjoiYXQrand0In0.eyJuYmYiOjE2MzE4ODg4MzYsImV4cCI6MTYzMTg5MjQzNiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo1MDAwIiwiY2xpZW50X2lkIjoic2ltcGxlX2NsaWVudCIsImp0aSI6IjRBNjI4QUNDODg3OTIxN0YzNzk4QTAwNTUyQjk5OTc4IiwiaWF0IjoxNjMxODg4ODM2LCJzY29wZSI6WyJzaW1wbGVfYXBpIl19.dfWw0h1bpHJy-NAyfOQBEAqthFStndAMPq7nWFAxabKm9A2Wlw4FE9t1bci2DZtgZftb4Uj4GHmibtGyqnTmc4z_OBdZ7llIW3o_LcbiUjMrefohOFGSyRuGVlbzRZb1pbcru8JoNG9k4bFrCLVWvNRUUcUTdVan6ydMkYqNQUg_NJKhKGW9n0HbuoE5nE2yM2eqHHB6IOd6uMYvWzlISfgWNvHlBGtXTGvBkfYjikf6yEz7FuKwuijDeLGPkAbb407ZzFCw-Qo_GV1I9Nzp3IrRe9n9oSSq3_h2plLuL8gNgP8L3Bb82k_LKS-wjBEtm9eLgAh1Mdn6nEL1ezutpg",
"expires_in": 3600,
"token_type": "Bearer",
"scope": "simple_api"
}

其中​​access_token​​​ ,这串字符串的结构就是jwt结构包装的令牌,我们可以将这个字符串放入​​https://jwt.ms​​ 来进行解密看看这到底包装了啥。

{
"alg": "RS256",
"kid": "9A25EAEE228D429D4C1D17563D72DA83",
"typ": "at+jwt"
}.{
"nbf": 1631888836,
"exp": 1631892436,
"iss": "https://localhost:5000",
"client_id": "simple_client",
"jti": "4A628ACC8879217F3798A00552B99978",
"iat": 1631888836,
"scope": [
"simple_api"
]
}.[Signature]
  • 测试客户端2(资源拥有者客户端:simple_pass_client )

​ client_id​​:simple_pass_client

​client_secret​​:simple_client_secret

​grant_type​​​:password(其实就是​​GrantType.ResourceOwnerPassword​​)

​username​​:admin(与Config类中资源拥有客户端一致)

​password​​:123(与Config类中资源拥有客户端一致)

{
"access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjZBQTAwQjMzQTExQzE1M0VGNTZDRkVCNzQ4RTZDQjQxIiwidHlwIjoiYXQrand0In0.eyJuYmYiOjE2MzIxNDk5MDgsImV4cCI6MTYzMjE1MzUwOCwiaXNzIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6NTAwMCIsImNsaWVudF9pZCI6InNpbXBsZV9wYXNzX2NsaWVudCIsInN1YiI6IjEiLCJhdXRoX3RpbWUiOjE2MzIxNDk5MDgsImlkcCI6ImxvY2FsIiwianRpIjoiNjg1QzZDQjBFRjVBQjEzMDhGM0Y1OTlFMDEwMDI3MDciLCJpYXQiOjE2MzIxNDk5MDgsInNjb3BlIjpbInNpbXBsZV9hcGkiXSwiYW1yIjpbInB3ZCJdfQ.tWCsFWnlMinuHvb4UTVK-GxSRUyhSX7GGZPYE05KsZt67K-yriNl1FBI5ZThAWU7qscrCSEBWk1yLd3LR8G3xqEyPkpT4j_xoPTToY7zOAgVHw6wJPV3NxsfzdN07AuYCiPTP9WR9DrWLWy4Iac5GxZ30pcwXNLhPugPRZLG6dUXwry18Dl8jstBHvBQSKGIcrm5HKGeKUxs2aXRg-rl2BmHedRUZK6IjGoABeeSbAUSMfsTOVMdZSXwhdznI6wsjV9YLq3-CerfCIri0BtHVmSJz7hqrq-mg88NK2CZzLEvmKzf73-FprWxdma-6xUEv6E-X4dgOAXt-EZPCSnzWA",
"expires_in": 3600,
"token_type": "Bearer",
"scope": "simple_api"
}

将access_token 放入https://jwt.ms 来进行解密查看结果,也可以与客户端1对比对比

{
"alg": "RS256",
"kid": "6AA00B33A11C153EF56CFEB748E6CB41",
"typ": "at+jwt"
}.{
"nbf": 1632149908,
"exp": 1632153508,
"iss": "https://localhost:5000",
"client_id": "simple_pass_client",
"sub": "1",
"auth_time": 1632149908,
"idp": "local",
"jti": "685C6CB0EF5AB1308F3F599E01002707",
"iat": 1632149908,
"scope": [
"simple_api"
],
"amr": [
"pwd"
]
}.[Signature]

Api 项目

  1. 创建一个空的asp.net core webapi
  2. 引用包​​Microsoft.AspNetCore.Authentication.Jwt​​ 用于做认证
  3. 新建一个普通的Api控制器,在需要认证的方法或者类上面加上​​[Authorize]​​标签
[Route("Identity")]
[Authorize("MyApiScope")] //MyApiScope 这个字符串与Startup配置一致
[ApiController]
public class IdentityController : ControllerBase
{
[Authorize]
public IActionResult Get()
{
//用户信息(此时只是为了模拟返回数据,正常开发时:换成访问数据库的代码就行)
return new JsonResult(from c in User.Claims select new {c.Type, c.Value});

}
}
  1. 修改Startup.cs 类中ConfigureServices 方法代码
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddAuthentication("Bearer").AddJwtBearer("Bearer", p =>
{
//oidc的服务地址(一定要用https!!)
p.Authority = "https://localhost:5000";//也就是IdentifyServer项目运行地址
//设置jwt的验证参数(默认情况下是不需要此验证的)
p.TokenValidationParameters = new TokenValidationParameters
{
ValidateAudience = false
};
});
//注册授权服务
services.AddAuthorization(p =>
{
//添加授权策略
p.AddPolicy("MyApiScope", opt =>
{
//配置鉴定用户的规则,也就是说必须通过身份认证
opt.RequireAuthenticatedUser();
//鉴定api范围的规则
opt.RequireClaim("scope", "simple_api");
});

});
}
  1. 在Startup.cs 类中的Configure方法添加认证方法,一定要放在​​app.UseAuthorization()​​ 前面:
app.UseAuthentication();
  1. 测试运行:​​http://localhost:6000/identity​​(注意,IdentifyServer 那个项目要最先运行),记得使用Bearer形式调用,也就是在请求头中加上Authorazition:Bearer access_token(注意Bearer后面有个空格),access_token 在上面已经获取到了
[
{
"type": "nbf",
"value": "1632061080"
},
{
"type": "exp",
"value": "1632064680"
},
{
"type": "iss",
"value": "https://localhost:5000"
},
{
"type": "client_id",
"value": "simple_client"
},
{
"type": "jti",
"value": "BE2D6DCEE4235509666475A049E58DDC"
},
{
"type": "iat",
"value": "1632061080"
},
{
"type": "scope",
"value": "simple_api"
}
]
# 控制台测试客户端(可选)

1. 新建一个控制台应用(实际开发时,使用WebMvc)

2. 引用`IdentityModel`,里面封装了

3. 在Main中编写代码:
//请求客户端(需要先安装IdentityModel)
//由于IdentityModel中大部分都是异步方法,为了方便,我们将Main方法也改成异步方法
//请求客户端(需要先安装IdentityModel)
//由于IdentityModel中大部分都是异步方法,为了方便,我们将Main方法也改成异步方法
static async Task Main(string[] args)
{

var client = new HttpClient();
//获取发现文件,也就是https://localhost:5000/.well-known/openid-configuration 这个地址的结果就是发现文档
var discoveryDocumentAsync = await client.GetDiscoveryDocumentAsync("https://localhost:5000");
if (discoveryDocumentAsync.IsError)
{
Console.WriteLine(discoveryDocumentAsync.Error);
}

//与请求https://localhost:5000/connect/token 这个是一个意思
var tokenResponse = await client.RequestClientCredentialsTokenAsync(
new ClientCredentialsTokenRequest()
{
Address = discoveryDocumentAsync.TokenEndpoint,//获取Token的方法地址(token_endpoint的值)
ClientId = "simple_client", //与Config类中一致
GrantType = OidcConstants.GrantTypes.ClientCredentials,
ClientSecret = "simple_client_secret" //与Config类中一致
}
);
if (tokenResponse.IsError)
{
Console.WriteLine(tokenResponse.Error);
}
// Console.WriteLine(tokenResponse.Json);


//此时已经拿到了accessToken,这时,就可以访问api了
var apiClient = new HttpClient { BaseAddress = new Uri("http://localhost:6000") };
apiClient.SetBearerToken(tokenResponse.AccessToken);//设置访问令牌
var httpResponseMessage = await apiClient.GetAsync("Identity");
var content = await httpResponseMessage.Content.ReadAsStringAsync();
Console.WriteLine(content);



//测试资源拥有者客户端
var resourceTokenResp = await client.RequestPasswordTokenAsync(
new PasswordTokenRequest()
{
Address = discoveryDocumentAsync.TokenEndpoint,//获取Token的方法地址(token_endpoint的值)
ClientId = "simple_pass_client", //与Config类中一致
GrantType = OidcConstants.GrantTypes.Password,
ClientSecret = "simple_client_secret", //与Config类中一致
UserName = "admin",
Password = "123"
}
);


var apiPassClient = new HttpClient { BaseAddress = new Uri("http://localhost:6000") };
apiPassClient.SetBearerToken(resourceTokenResp.AccessToken);//设置访问令牌
var httpPassResponseMessage = await apiPassClient.GetAsync("Identity");
var contentPass = await httpPassResponseMessage.Content.ReadAsStringAsync();
Console.WriteLine(contentPass);


Console.ReadKey();
}

添加IdentifyServer项目UI

  1. 在IdentifyServer下添加(github项目地址:)​IdentityServer4.Quickstart.UI
  2. 安装方式:
    在IdentityServer4项目下,打开cmd,执行如下命令
  • 第一步:​​ dotnet new -i IdentityServer4.Templates::4.0.1​​ ,4.0.1是版本号,如果不写则使用默认,这个取决于你安装的IdentifyServer4的版本
  • 第二步: ​​dotnet new is4ui​
  • 执行结果如下:
F:\workspace\code\练习\IdentifyServer4\Web.Client\IdentityServer>dotnet new -i IdentityServer4.Templates::4.0.1
正在确定要还原的项目…
已还原 C:\Users\Administrator\.templateengine\dotnetcli\v5.0.201\scratch\restore.csproj (用时 9.67 sec)。

Templates Short Name Language Tags
---------------------------------------------------- ------------------- ---------- ----------------------
Console Application console [C#],F#,VB Common/Console
Class library classlib [C#],F#,VB Common/Library
WPF Application wpf [C#],VB Common/WPF
WPF Class library wpflib [C#],VB Common/WPF
WPF Custom Control Library wpfcustomcontrollib [C#],VB Common/WPF
WPF User Control Library wpfusercontrollib [C#],VB Common/WPF
Windows Forms App winforms [C#],VB Common/WinForms
Windows Forms Control Library winformscontrollib [C#],VB Common/WinForms
Windows Forms Class Library winformslib [C#],VB Common/WinForms
Worker Service worker [C#],F# Common/Worker/Web
Unit Test Project mstest [C#],F#,VB Test/MSTest
NUnit 3 Test Project nunit [C#],F#,VB Test/NUnit
NUnit 3 Test Item nunit-test [C#],F#,VB Test/NUnit
xUnit Test Project xunit [C#],F#,VB Test/xUnit
Razor Component razorcomponent [C#] Web/ASP.NET
Razor Page page [C#] Web/ASP.NET
MVC ViewImports viewimports [C#] Web/ASP.NET
MVC ViewStart viewstart [C#] Web/ASP.NET
Blazor Server App blazorserver [C#] Web/Blazor
Blazor WebAssembly App blazorwasm [C#] Web/Blazor/WebAssembly
ASP.NET Core Empty web [C#],F# Web/Empty
IdentityServer4 with AdminUI is4admin [C#] Web/IdentityServer4
IdentityServer4 with ASP.NET Core Identity is4aspid [C#] Web/IdentityServer4
IdentityServer4 Empty is4empty [C#] Web/IdentityServer4
IdentityServer4 with Entity Framework Stores is4ef [C#] Web/IdentityServer4
IdentityServer4 with In-Memory Stores and Test Users is4inmem [C#] Web/IdentityServer4
IdentityServer4 Quickstart UI (UI assets only) is4ui [C#] Web/IdentityServer4
ASP.NET Core Web App (Model-View-Controller) mvc [C#],F# Web/MVC
ASP.NET Core Web App webapp [C#] Web/MVC/Razor Pages
ASP.NET Core with Angular angular [C#] Web/MVC/SPA
ASP.NET Core with React.js react [C#] Web/MVC/SPA
ASP.NET Core with React.js and Redux reactredux [C#] Web/MVC/SPA
Razor Class Library razorclasslib [C#] Web/Razor/Library
ASP.NET Core Web API webapi [C#],F# Web/WebAPI
ASP.NET Core gRPC Service grpc [C#] Web/gRPC
dotnet gitignore file gitignore Config
global.json file globaljson Config
NuGet Config nugetconfig Config
Dotnet local tool manifest file tool-manifest Config
Web Config webconfig Config
Solution File sln Solution
Protocol Buffer File proto Web/gRPC

Examples:
dotnet new mvc --auth Individual
dotnet new nunit -f net472
dotnet new --help
dotnet new is4admin --help

F:\workspace\code\练习\IdentifyServer4\Web.Client\IdentityServer>dotnet new is4ui
The template "IdentityServer4 Quickstart UI (UI assets only)" was created successfully.

F:\workspace\code\练习\IdentifyServer4\Web.Client\IdentityServer>

此时,你回到vs中,可以看到IdentityServer项目中会多出wwwroot,QuickStart,Views 这几个文件夹,表示成功了!!

友情提示:如果​​dotnet new -i IdentityServer4.Templates::4.0.1​​​ 命令如果已经执行过了,下次就不需要重新执行了,只需要执行​​dotnet new is4ui​​ 命令即可!!!

  1. 在Configure 方法中注册路由与授权
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseStaticFiles();
app.UseRouting();
app.UseIdentityServer();
app.UseAuthorization();
app.UseEndpoints(endpoint =>
{
endpoint.MapDefaultControllerRoute();
});
}

创建Mvc客户端(你的正文或者说你的系统)

这个客户端,其实就是你要做的系统。

  1. 创建项目Identity.MvcClient 项目(这个名字你随便写)
  2. 引用 ​​Microsoft.AspNetCore.Authentication.OpenIdConnect​
  3. 在你需要受保护的控制器或者视图上添加​​ [Authorize]​​标签
  4. 在startup.cs 类中 ​​ConfigureServices​​ 方法中添加oidc(OpenId Connect) 认证
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
JwtSecurityTokenHandler.DefaultMapInboundClaims = false;
services.AddAuthentication(p =>
{
p.DefaultScheme = "Cookies";
p.DefaultChallengeScheme = "oidc";

})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", p =>
{
p.Authority = "https://localhost:5000";//IdentityServer 项目的运行地址,一定要用Https
p.ClientId = "simple_mvc_client";
p.ClientSecret = "simple_client_secret";
p.ResponseType = "code";//使用授权码形式
p.SaveTokens = true; //把令牌保存在cookie里
p.Scope.Add("simple_api");//验证令牌中,是否包含simple_api
});
}
  1. 在 Configure方法添加认证中间件,注意:必须放在​​app.UseAuthorization()​​前面
app.UseAuthentication();
  1. 运行IdentityServer项目与Mvc项目,此时,如果访问受保护的资源时,则到自动跳转至IdentityServer项目登录页面,登录成功之后,会立即返回刚刚你所访问的受保护的资源页面,配置成功!!
  2. 实现退出登录。随意在一个控制器中创建一个方法,表示退出登录
//实现退出页面
public IActionResult Logout()
{
//清除Cookies,与oidc信息
return SignOut("Cookies", "oidc");
}

配置EF Core

  1. 在IdentityServer 项目中添加引用:​​IdentityServer4.EntityFramework​​​​IdentityServer4.EntityFramework​​ implements the required stores and services using the following DbContexts:
  • ConfigurationDbContext - used for configuration data such as clients, resources, and scopes
  • PersistedGrantDbContext - used for temporary operational data such as authorization codes, and refresh tokens
  1. 在IdentityServer 项目中添加引用:​​Microsoft.EntityFrameworkCore.SqlServer​
  2. Startup.cs 中配置:
var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;
const string connectionString = @"server=.;uid=sa;pwd=123456;database=ids4_oauth;trusted_connection=yes;";

services.AddIdentityServer()
.AddConfigurationStore(options =>
{
options.ConfigureDbContext = b => b.UseSqlServer(connectionString,
sql => sql.MigrationsAssembly(migrationsAssembly));
})
.AddOperationalStore(options =>
{
options.ConfigureDbContext = b => b.UseSqlServer(connectionString,
sql => sql.MigrationsAssembly(migrationsAssembly));
});
  1. 安装install the Entity Framework Core CLI 环境
dotnet tool install --global dotnet-ef --version 3.1.19

引用包:​​Microsoft.EntityFrameworkCore.Design​

  1. 在IdentifyServer项目文件夹中,打开命令行工具,执行数据迁移命令
dotnet ef migrations add InitialIdentityServerPersistedGrantDbMigration -c PersistedGrantDbContext -o Data/Migrations/IdentityServer/PersistedGrantDb

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

dotnet ef migrations add InitialApplicationDbMigration -c ApplicationDbContext -o Data/Migrations/IdentityServer/ApplicationDb
或者
在程序包管理控制台:
add-migration InitApplicationDbMigration -c ApplicationDbContext
update-database InitApplicationDbMigration -c ApplicationDbContext

此时在​​~/Data/Migrations/IdentityServer​​下就会有你新创建的代码了

6.在Startup.cs 类中,初始化数据库,

public void Configure(IApplicationBuilder app)
{
// this will do the initial DB population
InitializeDatabase(app);

// the rest of the code that was already here
// ...
}
private void InitializeDatabase(IApplicationBuilder app)
{
using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
{
serviceScope.ServiceProvider.GetRequiredService<PersistedGrantDbContext>().Database.Migrate();

var context = serviceScope.ServiceProvider.GetRequiredService<ConfigurationDbContext>();
context.Database.Migrate();
if (!context.Clients.Any())
{
foreach (var client in Config.Clients)
{
context.Clients.Add(client.ToEntity());
}
context.SaveChanges();
}

if (!context.IdentityResources.Any())
{
foreach (var resource in Config.IdentityResources)
{
context.IdentityResources.Add(resource.ToEntity());
}
context.SaveChanges();
}

if (!context.ApiScopes.Any())
{
foreach (var resource in Config.ApiScopes)
{
context.ApiScopes.Add(resource.ToEntity());
}
context.SaveChanges();
}
}
}

安装IdentityServer4 证书

  1. 安装OpenSSL工具 ,官网下载地址:https://slproweb.com/products/Win32OpenSSL.html
  2. 在CMD中执行以下命令

openssl req -newkey rsa:2048 -nodes -keyout cas.clientservice.key -x509 -days 365 -out cas.clientservice.cer


标签:Web,入门,C#,simple,client,https,new,IdentityServer4
From: https://blog.51cto.com/u_14452299/6019780

相关文章

  • HBase 快速入门(安装和命令操作)
    1HBase安装部署1.1Zookeeper正常部署首先保证Zookeeper集群的正常部署,并启动。bin/zkServer.shstartbin/zkServer.shstartbin/zkServer.shstart1.2Hadoop正常部......
  • 230118_50_SpringBoot入门
    yaml配置文件中,支持占位符配置person:name:bill${random.int}age:4happy:truebirth:2023/01/15maps:{k1:v1,k2:v2}hello:hellolists:-cat-dog-fish......
  • node+express+ multer 实现文件上传入门
    文件上传文件上传需要借助一个中间件multer因此我们需要安装cnpminstallmulter--save前端界面在express创建的项目下的public/upload目录下创建indexfileuplo......
  • 这可能是Matplotlib和Seaborn最全的入门文档
    matplotlib是python第一个数据可视化库,在数据分析,可视化领域的地位和贡献是无法磨灭的。但也正是因为有了这位老大哥的出现给后续基于matplotlib实现的绘图库实现了可能。......
  • 分块入门详解(比较全面)
    最近写了几个分块,顺便做一下笔记。什么是分块分块是一种数据结构。。有许多数据结构都是\(\mathrm{log}\)数据结构,比如线段树,树状数组等等。他们复杂度优秀,但是都是树......
  • 【OI】值域分块入门
    相信很多人在学习莫队,刷莫队题目时,回不可避免的遇到一个数据结构——值域分块。这篇文章就是帮助各位快速入门的。Q1给定一个序列,实现单点修改以及区间查询,保证修改次......
  • Unity3D入门基础知识
    一、基础概念1、物体与空物体物体(GameObject),其实是一个节点或容器。一般所谓的“物体”,即有形状的东西,对应的Mesh,网格信息代表了物体(形状)。空物体(EmptyObject),即空对象......
  • C++入门篇之重载运算符和重载函数
    C++允许在同一作用域中的某个函数 和运算符 指定多个定义,分别称为函数重载 和运算符重载。重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声......
  • C++入门篇之C++ 指针
    学习C++的指针既简单又有趣。通过指针,可以简化一些C++编程任务的执行,还有一些任务,如动态内存分配,没有指针是无法执行的。所以,想要成为一名优秀的C++程序员,学习指针是......
  • c++入门篇之C++ 多态
    多态按字面的意思就是多种形态。当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态。C++多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数......