IdentityServer4入门

IdentityServer4入门IdentityServ 是用于 ASP NETCore 的 OpenIDConnec 和 OAuth2 0 框架 官网 https identityserv readthedocs io en latest 创建 Asp netWebCore 空模板项目 可以将基命名为 IdentityServ 名称可以随意 一般都取这个 注意必须配置 Https 引用 IdentityServ 配置 Config 必须是 static 类在中的方法中配置如下 在中的配置如下代码

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 类
    ///  /// IdentityServer4配置类 ///  public static class Config { 
          ///  /// Api范围 ///  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": , "exp": , "iss": "https://localhost:5000", "client_id": "simple_client", "jti": "4A628ACCF3798A00552B99978", "iat": , "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": , "exp": , "iss": "https://localhost:5000", "client_id": "simple_pass_client", "sub": "1", "auth_time": , "idp": "local", "jti": "685C6CB0EF5AB1308F3F599E0", "iat": , "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}); } } 
  4. 修改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"); }); }); } 
  5. 在Startup.cs 类中的Configure方法添加认证方法,一定要放在app.UseAuthorization() 前面:
     app.UseAuthentication(); 
  6. 测试运行:http://localhost:6000/identity(注意,IdentifyServer 那个项目要最先运行),记得使用Bearer形式调用,也就是在请求头中加上Authorazition:Bearer access_token(注意Bearer后面有个空格),access_token 在上面已经获取到了
[ { 
    "type": "nbf", "value": "" }, { 
    "type": "exp", "value": "" }, { 
    "type": "iss", "value": "https://localhost:5000" }, { 
    "type": "client_id", "value": "simple_client" }, { 
    "type": "jti", "value": "BE2D6DCEE75A049E58DDC" }, { 
    "type": "iat", "value": "" }, { 
    "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
  2. 在IdentityServer 项目中添加引用:Microsoft.EntityFrameworkCore.SqlServer
  3. Startup.cs 中配置:
    var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name; const string connectionString = @"server=.;uid=sa;pwd=;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)); }); 
  4. 安装install the Entity Framework Core CLI 环境
    dotnet tool install --global dotnet-ef --version 3.1.19 

    引用包:Microsoft.EntityFrameworkCore.Design

  5. 在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 证书

https://www.cnblogs.com/chenyishi/p/10922326.html

  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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/202481.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月20日 上午7:02
下一篇 2026年3月20日 上午7:02


相关推荐

  • acwing1185. 单词游戏(欧拉图)「建议收藏」

    acwing1185. 单词游戏(欧拉图)「建议收藏」有 N 个盘子,每个盘子上写着一个仅由小写字母组成的英文单词。你需要给这些盘子安排一个合适的顺序,使得相邻两个盘子中,前一个盘子上单词的末字母等于后一个盘子上单词的首字母。请你编写一个程序,判断是否能达到这一要求。输入格式第一行包含整数 T,表示共有 T 组测试数据。每组数据第一行包含整数 N,表示盘子数量。接下来 N 行,每行包含一个小写字母字符串,表示一个盘子上的单词。一个单词可能出现多次。输出格式如果存在合法解,则输出”Ordering is possible.”,否则输出”The

    2022年8月9日
    5
  • lan8742a_工业互联-Microchip极佳以太网物理层收发器KSZ8041/LAN8720A推荐

    lan8742a_工业互联-Microchip极佳以太网物理层收发器KSZ8041/LAN8720A推荐原标题:工业互联-Microchip极佳以太网物理层收发器KSZ8041/LAN8720A推荐Microchip推出多款拥有高级功能、合规认证、全面的软件支持和产品化评估工具的以太网芯片组合,帮助降低高速网络部署的复杂性和消除部署过程中的障碍,并致力为客户提供完善的高可靠性以太网产品平台,帮助客户易于获得设计资源和简化产品设计。KSZ8041NLMicrochip公司KSZ8041NL,其内核可在…

    2022年6月22日
    65
  • java interface 介绍

    java interface 介绍interface 类似于 class 只不过 interface 里的所有方法都是 abstract 抽象的 当一个非抽象的 class 实现 implements 一个接口 interface 时 必须实现接口中所有方法 因为都是 abstract 抽象的 否则该 class 必须声明为 abstract sample1 interfaceusa publicclass

    2026年3月26日
    2
  • Linux云服务器挖矿病毒(crypto和pnscan)导致CPU占用100%问题解决方案「建议收藏」

    Linux云服务器挖矿病毒(crypto和pnscan)导致CPU占用100%问题解决方案「建议收藏」木马攻击问题由来阐述我买了三年的阿里云服务器(在阿里云官网买的),已经使用了一年多了,平时拿来搭建网站,有时也拿来学习技术和开发测试,一直使用很稳定。直到近期我服务器上安装了docker并部署了springboot+mysql+nginx项目,就被攻击了。但就在今年的5月14号,我的服务器被木马攻击,然后被拿去挖矿了。我服务器的cpu持续维持在CPU100%.后果是直接导致我网站无法正常请求和响应。而且Linux服务器的root权限被窃取了。黑客在服务器/root/.ssh目录下生成了连root用户

    2022年5月1日
    58
  • pychram2021.11.3激活【2021免费激活】

    (pychram2021.11.3激活)最近有小伙伴私信我,问我这边有没有免费的intellijIdea的激活码,然后我将全栈君台教程分享给他了。激活成功之后他一直表示感谢,哈哈~https://javaforall.net/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~9ZHR…

    2022年3月28日
    60
  • Only fullscreen activities can request orientation终极解决方法

    Only fullscreen activities can request orientation终极解决方法适配到安卓 O 适配了 Service 通知等等 天真的以为一切都结束了 换菊花厂手机试 APP 直接 crash 这简直是何等的卧槽 错误提示如下 还有一种和这个差不多 就差一个单词 一个是 onCreate 时候 另一个是设置方向之后 Onlyfullscre 先参考了一下网上各位大佬的文章 以下面的为例 https

    2026年3月17日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号