1.ClientCredential 适用于不代表用户的客户端访问api资源,示例是用模板生成的代码做的更改
2.identityServer配置
Startup
1 public class Startup 2 { 3 public IHostingEnvironment Environment { get; } 4 public IConfiguration Configuration { get; } 5 6 public Startup(IHostingEnvironment environment, IConfiguration configuration) 7 { 8 Environment = environment; 9 Configuration = configuration; 10 } 11 12 public void ConfigureServices(IServiceCollection services) 13 { 14 services.AddMvc().SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Version_2_1); 15 16 services.Configure<IISOptions>(options => 17 { 18 options.AutomaticAuthentication = false; 19 options.AuthenticationDisplayName = "Windows"; 20 }); 21 22 var builder = services.AddIdentityServer(options => 23 { 24 options.Events.RaiseErrorEvents = true; 25 options.Events.RaiseInformationEvents = true; 26 options.Events.RaiseFailureEvents = true; 27 options.Events.RaiseSuccessEvents = true; 28 }) 29 .AddTestUsers(TestUsers.Users); 30 31 // in-memory, code config 32 builder.AddInMemoryIdentityResources(Config.GetIdentityResources()); 33 builder.AddInMemoryApiResources(Config.GetApis()); 34 builder.AddInMemoryClients(Config.GetClients()); 35 36 // in-memory, json config 37 //builder.AddInMemoryIdentityResources(Configuration.GetSection("IdentityResources")); 38 //builder.AddInMemoryApiResources(Configuration.GetSection("ApiResources")); 39 //builder.AddInMemoryClients(Configuration.GetSection("clients")); 40 41 if (Environment.IsDevelopment()) 42 { 43 builder.AddDeveloperSigningCredential(); 44 } 45 else 46 { 47 throw new Exception("need to configure key material"); 48 } 49 50 services.AddAuthentication() 51 .AddGoogle(options => 52 { 53 options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme; 54 55 // register your IdentityServer with Google at https://console.developers.google.com 56 // enable the Google+ API 57 // set the redirect URI to http://localhost:5000/signin-google 58 options.ClientId = "copy client ID from Google here"; 59 options.ClientSecret = "copy client secret from Google here"; 60 }); 61 } 62 63 public void Configure(IApplicationBuilder app) 64 { 65 if (Environment.IsDevelopment()) 66 { 67 app.UseDeveloperExceptionPage(); 68 } 69 70 app.UseIdentityServer(); 71 app.UseStaticFiles(); 72 app.UseMvcWithDefaultRoute(); 73 } 74 }
Config
1 public static class Config 2 { 3 public static IEnumerable<IdentityResource> GetIdentityResources() 4 { 5 return new IdentityResource[] 6 { 7 new IdentityResources.OpenId(), 8 new IdentityResources.Profile(), 9 }; 10 } 11 12 public static IEnumerable<ApiResource> GetApis() 13 { 14 return new ApiResource[] 15 { 16 new ApiResource("api1", "My API #1") 17 }; 18 } 19 20 public static IEnumerable<Client> GetClients() 21 { 22 return new[] 23 { 24 // client credentials flow client 25 new Client 26 { 27 ClientId = "console client", 28 ClientName = "Client Credentials Client", 29 30 AllowedGrantTypes = GrantTypes.ClientCredentials, 31 ClientSecrets = { new Secret("511536EF-F270-4058-80CA-1C89C192F69A".Sha256()) }, 32 33 AllowedScopes = { "api1" } 34 } 35 36 // MVC client using hybrid flow 37 //new Client 38 //{ 39 // ClientId = "mvc", 40 // ClientName = "MVC Client", 41 42 // AllowedGrantTypes = GrantTypes.HybridAndClientCredentials, 43 // ClientSecrets = { new Secret("49C1A7E1-0C79-4A89-A3D6-A37998FB86B0".Sha256()) }, 44 45 // RedirectUris = { "http://localhost:5001/signin-oidc" }, 46 // FrontChannelLogoutUri = "http://localhost:5001/signout-oidc", 47 // PostLogoutRedirectUris = { "http://localhost:5001/signout-callback-oidc" }, 48 49 // AllowOfflineAccess = true, 50 // AllowedScopes = { "openid", "profile", "api1" } 51 //}, 52 53 //// SPA client using implicit flow 54 //new Client 55 //{ 56 // ClientId = "spa", 57 // ClientName = "SPA Client", 58 // ClientUri = "http://identityserver.io", 59 60 // AllowedGrantTypes = GrantTypes.Implicit, 61 // AllowAccessTokensViaBrowser = true, 62 63 // RedirectUris = 64 // { 65 // "http://localhost:5002/index.html", 66 // "http://localhost:5002/callback.html", 67 // "http://localhost:5002/silent.html", 68 // "http://localhost:5002/popup.html", 69 // }, 70 71 // PostLogoutRedirectUris = { "http://localhost:5002/index.html" }, 72 // AllowedCorsOrigins = { "http://localhost:5002" }, 73 74 // AllowedScopes = { "openid", "profile", "api1" } 75 //} 76 }; 77 } 78 }
3.apiSource
Startup
1 public class Startup 2 { 3 // This method gets called by the runtime. Use this method to add services to the container. 4 // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 5 public void ConfigureServices(IServiceCollection services) 6 { 7 services.AddMvcCore() 8 .AddAuthorization() 9 .AddJsonFormatters(); 10 11 services.AddAuthentication("Bearer") 12 .AddJwtBearer("Bearer", options => 13 { 14 options.Authority = "http://localhost:5000"; 15 options.RequireHttpsMetadata = false; 16 17 options.Audience = "api1"; 18 }); 19 } 20 21 // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 22 public void Configure(IApplicationBuilder app, IHostingEnvironment env) 23 { 24 app.UseAuthentication(); 25 app.UseMvc(); 26 } 27 }
4.客户端调用
1 class Program 2 { 3 static async Task Main(string[] args) 4 { 5 var client = new HttpClient(); 6 7 var disco = await client.GetDiscoveryDocumentAsync("http://localhost:5000"); 8 9 if (disco.IsError) 10 { 11 Console.WriteLine(disco.Error); 12 return; 13 } 14 15 var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest 16 { 17 Address = disco.TokenEndpoint, 18 ClientId = "console client", 19 ClientSecret = "511536EF-F270-4058-80CA-1C89C192F69A", 20 Scope = "api1" 21 }); 22 23 if (tokenResponse.IsError) 24 { 25 Console.WriteLine(tokenResponse.Error); 26 return; 27 } 28 29 30 var apiClient = new HttpClient(); 31 apiClient.SetBearerToken(tokenResponse.AccessToken); 32 var response = await apiClient.GetAsync("http://localhost:5001/api/Values"); 33 34 if (!response.IsSuccessStatusCode) 35 { 36 Console.WriteLine(response.StatusCode); 37 } 38 else 39 { 40 var content = await response.Content.ReadAsStringAsync(); 41 Console.WriteLine(JArray.Parse(content)); 42 } 43 44 45 46 Console.ReadKey(); 47 48 } 49 }