https://identityserver4.readthedocs.io/en/release/quickstarts/8_entity_framework.html 此连接的实践
vscode 下面命令
dotnet new webapi -o is4ef
cd is4ef
dotnet add package IdentityServer4.EntityFramework
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
dotnet add package Microsoft.EntityFrameworkCore.Tools
增加Config.cs
1 // Copyright (c) Brock Allen & Dominick Baier. All rights reserved. 2 // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 4 using IdentityServer4; 5 using IdentityServer4.Models; 6 using IdentityServer4.Test; 7 using System.Collections.Generic; 8 using System.Security.Claims; 9 10 namespace is4ef 11 { 12 public class Config 13 { 14 // scopes define the resources in your system 15 public static IEnumerable<IdentityResource> GetIdentityResources() 16 { 17 return new List<IdentityResource> 18 { 19 new IdentityResources.OpenId(), 20 new IdentityResources.Profile(), 21 }; 22 } 23 24 public static IEnumerable<ApiResource> GetApiResources() 25 { 26 return new List<ApiResource> 27 { 28 new ApiResource("api1", "My API") 29 }; 30 } 31 32 // clients want to access resources (aka scopes) 33 public static IEnumerable<Client> GetClients() 34 { 35 // client credentials client 36 return new List<Client> 37 { 38 new Client 39 { 40 ClientId = "client", 41 AllowedGrantTypes = GrantTypes.ClientCredentials, 42 43 ClientSecrets = 44 { 45 new Secret("secret".Sha256()) 46 }, 47 AllowedScopes = { "api1" } 48 }, 49 50 // resource owner password grant client 51 new Client 52 { 53 ClientId = "ro.client", 54 AllowedGrantTypes = GrantTypes.ResourceOwnerPassword, 55 56 ClientSecrets = 57 { 58 new Secret("secret".Sha256()) 59 }, 60 AllowedScopes = { "api1" } 61 }, 62 63 // OpenID Connect hybrid flow and client credentials client (MVC) 64 new Client 65 { 66 ClientId = "mvc", 67 ClientName = "MVC Client", 68 AllowedGrantTypes = GrantTypes.HybridAndClientCredentials, 69 70 ClientSecrets = 71 { 72 new Secret("secret".Sha256()) 73 }, 74 75 RedirectUris = { "http://localhost:5002/signin-oidc" }, 76 PostLogoutRedirectUris = { "http://localhost:5002/signout-callback-oidc" }, 77 78 AllowedScopes = 79 { 80 IdentityServerConstants.StandardScopes.OpenId, 81 IdentityServerConstants.StandardScopes.Profile, 82 "api1" 83 }, 84 AllowOfflineAccess = true 85 } 86 }; 87 } 88 89 public static List<TestUser> GetUsers() 90 { 91 return new List<TestUser> 92 { 93 new TestUser 94 { 95 SubjectId = "1", 96 Username = "alice", 97 Password = "password", 98 99 Claims = new List<Claim> 100 { 101 new Claim("name", "Alice"), 102 new Claim("website", "https://alice.com") 103 } 104 }, 105 new TestUser 106 { 107 SubjectId = "2", 108 Username = "bob", 109 Password = "password", 110 111 Claims = new List<Claim> 112 { 113 new Claim("name", "Bob"), 114 new Claim("website", "https://bob.com") 115 } 116 } 117 }; 118 } 119 } 120 }
Startup.cs->ConfigureServices
using Microsoft.EntityFrameworkCore; using System.Reflection;
1 const string connectionString = @"Data Source=(LocalDb)\MSSQLLocalDB;database=IdentityServer4.Quickstart.EntityFramework-2.0.0;trusted_connection=yes;"; 2 var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name; 3 4 // configure identity server with in-memory stores, keys, clients and scopes 5 services.AddIdentityServer() 6 .AddDeveloperSigningCredential() 7 .AddTestUsers(Config.GetUsers()) 8 // this adds the config data from DB (clients, resources) 9 .AddConfigurationStore(options => 10 { 11 options.ConfigureDbContext = builder => 12 builder.UseSqlServer(connectionString, 13 sql => sql.MigrationsAssembly(migrationsAssembly)); 14 }) 15 // this adds the operational data from DB (codes, tokens, consents) 16 .AddOperationalStore(options => 17 { 18 options.ConfigureDbContext = builder => 19 builder.UseSqlServer(connectionString, 20 sql => sql.MigrationsAssembly(migrationsAssembly)); 21 22 // this enables automatic token cleanup. this is optional. 23 options.EnableTokenCleanup = true; 24 options.TokenCleanupInterval = 30; 25 });
然后是生成数据库映像文件
1 dotnet ef migrations add InitialIdentityServerPersistedGrantDbMigration -c PersistedGrantDbContext -o Data/Migrations/IdentityServer/PersistedGrantDb 2 dotnet ef migrations add InitialIdentityServerConfigurationDbMigration -c ConfigurationDbContext -o Data/Migrations/IdentityServer/ConfigurationDb
然后是插入种子数据
1 private void InitializeDatabase(IApplicationBuilder app) 2 { 3 using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope()) 4 { 5 serviceScope.ServiceProvider.GetRequiredService<PersistedGrantDbContext>().Database.Migrate(); 6 7 var context = serviceScope.ServiceProvider.GetRequiredService<ConfigurationDbContext>(); 8 context.Database.Migrate(); 9 if (!context.Clients.Any()) 10 { 11 foreach (var client in Config.GetClients()) 12 { 13 context.Clients.Add(client.ToEntity()); 14 } 15 context.SaveChanges(); 16 } 17 18 if (!context.IdentityResources.Any()) 19 { 20 foreach (var resource in Config.GetIdentityResources()) 21 { 22 context.IdentityResources.Add(resource.ToEntity()); 23 } 24 context.SaveChanges(); 25 } 26 27 if (!context.ApiResources.Any()) 28 { 29 foreach (var resource in Config.GetApiResources()) 30 { 31 context.ApiResources.Add(resource.ToEntity()); 32 } 33 context.SaveChanges(); 34 } 35 } 36 }
Startup.cs->Configure 配置注入
1 InitializeDatabase(app);
最后还有两个要引用
using IdentityServer4.EntityFramework.DbContexts; using IdentityServer4.EntityFramework.Mappers;