1.新建三个项目
IdentityServer:端口5000
IdentityAPI:端口5001
IdentityClient:
2.在IdentityServer项目中添加IdentityServer4的包:Install-Package IdentityServer4
添加一个类:
public static IEnumerable<ApiResource> GetApiResources() { return new List<ApiResource> { new ApiResource("api", "myapi")//定义资源名称 }; } public static IEnumerable<Client> GetClients() { return new List<Client> { new Client { ClientId = "client",//客户端获取token时指定的ClientId值 AllowedGrantTypes = GrantTypes.ClientCredentials,//授权模式 ClientSecrets = { new Secret("secret".Sha256())//客户端获取token时指定的Secret值 }, AllowedScopes = { "api" }//设置可访问的资源名称 } }; }
然后在该项目的Startup中注入:
public class Startup { public void ConfigureServices(IServiceCollection services) { //注入到容器中 services.AddIdentityServer() .AddDeveloperSigningCredential() .AddInMemoryApiResources(Config.GetApiResources())//加载配置信息 .AddInMemoryClients(Config.GetClients()); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseIdentityServer();//管道 } }
然后你可以访问http://localhost:5000/.well-known/openid-configuration
3.在IdentityAPI项目中添加一个控制器:控制器头要添加[
添加身份验证中间件:① 验证传入令牌以确保它来自可信发行者,② 令牌验证是有效的,用于在这个API
Microsoft.AspNetCore.Authentication.JwtBearer
在该项目的Startup文件中
public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddMvcCore() .AddAuthorization() .AddJsonFormatters(); services.AddAuthentication("Bearer") .AddIdentityServerAuthentication(options => //使用IdentityServer作为授权模式 { options.Authority = "http://localhost:5000";//服务地址 options.RequireHttpsMetadata = false; options.ApiName = "api";//访问的资源名称 }); } public void Configure(IApplicationBuilder app) { app.UseAuthentication(); app.UseMvc(); } }
4.IdentityClient项目中添加IdentityModel 库
IdentityModel 包含了一个用于发现端点的客户端库。这样一来你只需要知道 IdentityServer 的基础地址,实际的端点地址可以从元数据中读取。
private static async Task MainAsync() { var disco = await DiscoveryClient.GetAsync("http://localhost:5000"); if (disco.IsError) { Console.WriteLine(disco.Error); return; } // request token var tokenClient = new TokenClient(disco.TokenEndpoint, "client", "secret"); var tokenResponse = await tokenClient.RequestClientCredentialsAsync("api"); if (tokenResponse.IsError) { Console.WriteLine(tokenResponse.Error); return; } Console.WriteLine(tokenResponse.Json); Console.WriteLine(" "); // call api var client = new HttpClient(); client.SetBearerToken(tokenResponse.AccessToken); var response = await client.GetAsync("http://localhost:5001/Home"); if (!response.IsSuccessStatusCode) { Console.WriteLine(response.StatusCode); } else { var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(JArray.Parse(content)); } Console.Read(); }
客户端授权模式通常用于服务器到服务器通信