基于 IdentityServer3 实现 OAuth 2.0 授权服务【密码模式(Resource Owner Password Credentials)】
密码模式(Resource Owner Password Credentials Grant)中,用户向客户端提供自己的用户名和密码。客户端使用这些信息,向"服务商提供商"索要授权。基于之前的 IdentityServer3 实现 OAuth 2.0 授权服务【客户端模式(Client Credentials Grant)】 修改。
客户端
public class Clients { public static List<Client> Get() { return new List<Client> { // no human involved new Client { ClientName = "App接口服务", ClientId = "app_test_id", Enabled = true, AccessTokenType = AccessTokenType.Reference, Flow = Flows.ClientCredentials, ClientSecrets = new List<Secret> { new Secret("F621F470-9731-4A25-80EF-67A6F7C5F4B8".Sha256()) }, AllowedScopes = new List<string> { "user", "order" } }, // human is involved new Client { ClientName = "username client", ClientId = "irving", Enabled = true, AccessTokenType = AccessTokenType.Reference, Flow = Flows.ResourceOwner, ClientSecrets = new List<Secret> { new Secret("21B5F798-BE55-42BC-8AA8-0025B903DC3B".Sha256()) }, AllowedScopes = new List<string> { "user", "order" } } }; } }
用户
public class Users { public static List<InMemoryUser> Get() { return new List<InMemoryUser> { new InMemoryUser { Username = "irving", Password = "123456", Subject = "1", Claims = new[] { new Claim(Constants.ClaimTypes.GivenName, "Bob"), new Claim(Constants.ClaimTypes.FamilyName, "Smith") } }, new InMemoryUser { Username = "bob", Password = "secret", Subject = "2" }, new InMemoryUser { Username = "alice", Password = "secret", Subject = "3" } }; } }
服务端配置
public class Startup { /// <summary> /// 配置idsv授权服务 /// </summary> /// <param name="app"></param> public void Configuration(IAppBuilder app) { var opts = new IdentityServerOptions { SiteName = "Embedded Homeinns PMS 2.0 OAuth2 Service", EnableWelcomePage = true, Factory = new IdentityServerServiceFactory() .UseInMemoryClients(Clients.Get()) .UseInMemoryScopes(Scopes.Get()) //.UseInMemoryUsers(new List<InMemoryUser>()), .UseInMemoryUsers(Users.Get()), RequireSsl = false, //SigningCertificate = new X509Certificate2(string.Format(@"{0}\bin\identityServer\idsrv3test.pfx", AppDomain.CurrentDomain.BaseDirectory), "idsrv3test") }; app.UseIdentityServer(opts); /* //自定义路由 app.Map("/identity", idsrvApp => { idsrvApp.UseIdentityServer(opts); }); */ }
控制器
[Route("api/v1/values")] public class ValuesController : ApiController { public IHttpActionResult Get() { var caller = User as ClaimsPrincipal; var subjectClaim = caller.FindFirst("sub"); if (subjectClaim != null) { return Json(new { message = "OK user", client = caller.FindFirst("client_id").Value, subject = subjectClaim.Value }); } else { return Json(new { message = "OK computer", client = caller.FindFirst("client_id").Value }); } } }
控制台
class Program { static void Main(string[] args) { /* POST http://192.168.210.165/connect/token HTTP/1.1 Accept: application/json Authorization: Basic YXBwX3Rlc3RfaWQ6RjYyMUY0NzAtOTczMS00QTI1LTgwRUYtNjdBNkY3QzVGNEI4 Content-Type: application/x-www-form-urlencoded Host: 192.168.210.165 Content-Length: 40 Expect: 100-continue Connection: Keep-Alive grant_type=client_credentials&scope=user */ /* GET http://192.168.210.165:88/api/v1/values HTTP/1.1 Authorization: Bearer 9f82476751e1f8b93f1ea6df7de83b51 Host: 192.168.210.165:88 */ var log = new LoggerConfiguration() .WriteTo .LiterateConsole(outputTemplate: "{Timestamp:HH:mm} [{Level}] ({Name:l}){NewLine} {Message}{NewLine}{Exception}") .CreateLogger(); //ClientCredentials var token = new TokenClient( "http://192.168.210.165/connect/token", "app_test_id", "F621F470-9731-4A25-80EF-67A6F7C5F4B8"); var response = token.RequestClientCredentialsAsync("user").Result; var client = new HttpClient(); client.SetBearerToken(response.AccessToken); log.Information(client.GetStringAsync("http://192.168.210.165:88/api/v1/values").Result); //ResourceOwner var resourceOwnerClient = new TokenClient( "http://192.168.210.165/connect/token", "irving", "21B5F798-BE55-42BC-8AA8-0025B903DC3B"); var data = resourceOwnerClient.RequestResourceOwnerPasswordAsync("irving", "123456", "order").Result; client.SetBearerToken(data.AccessToken); log.Information(client.GetStringAsync("http://192.168.210.165:88/api/v1/values").Result); Console.ReadKey(); } } }