IdentityServer4 密码模式实现
1. 修改 Config.cs
using System.Collections; using System.Collections.Generic; using IdentityServer4.Models; using IdentityServer4.Test;//测试的时候使用 namespace IdentityServiceSample { public class Config { public static IEnumerable<ApiResource> GetResource() { return new List<ApiResource>(){ new ApiResource("api","my api") }; } public static IEnumerable<Client> GetClients() { return new List<Client>(){ new Client(){ ClientId="client", //客户端模式 AllowedGrantTypes=GrantTypes.ClientCredentials, ClientSecrets={new Secret("secret".Sha256())}, AllowedScopes={"api"} }, new Client(){ ClientId="pwdClient", //OAuth密码模式 AllowedGrantTypes=GrantTypes.ResourceOwnerPassword, ClientSecrets={new Secret("secret".Sha256())}, AllowedScopes={"api"} } }; } //TODO 实际使用可以读取Db public static List<TestUser> GetTestUser() { return new List<TestUser>{ new TestUser{ SubjectId="1", Username="sunxuchu", Password="123456" } }; } } }
2. 修改 Startup.cs
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.HttpsPolicy; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using IdentityServer4; namespace IdentityServiceSample { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { //1.注入IdentityServer services.AddIdentityServer() .AddDeveloperSigningCredential() .AddInMemoryApiResources(Config.GetResource()) .AddInMemoryClients(Config.GetClients()) .AddTestUsers(Config.GetTestUser()); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseHsts(); } // app.UseHttpsRedirection(); // app.UseMvc(); //2. 注册IdentityServer app.UseIdentityServer(); } } }
3. 使用PostMan 调用调试
请求参数:
client_id:pwdClient
client_secret:secret
grant_type:password
password:123456
username:sunxuchu
4. 密码模式HttpClient 模拟请求
using System; using System.Net.Http; using IdentityModel.Client; namespace PwdClient { class Program { static void Main(string[] args) { try { new Program().GetAsync(); } catch (Exception ex) { System.Console.WriteLine(ex.Message); } Console.ReadKey(); } public async void GetAsync() { var diso = await DiscoveryClient.GetAsync("http://localhost:5003"); if (diso.IsError) { System.Console.WriteLine("diso.Error"); } var tokenClient = new TokenClient(diso.TokenEndpoint, "pwdClient", "secrt"); var tokenResponse = await tokenClient.RequestResourceOwnerPasswordAsync("sunxuchu","123456"); if (tokenResponse.IsError) { System.Console.WriteLine(tokenResponse.Error); } else { System.Console.WriteLine(tokenResponse.Json); } using (var httpClient = new HttpClient()) { httpClient.SetBearerToken(tokenResponse.AccessToken); var response = await httpClient.GetAsync("http://localhost:5001/api/values"); if (response.IsSuccessStatusCode) { System.Console.WriteLine(await response.Content.ReadAsStringAsync()); } } } } }