新建WinForm程序

image.png
Client Credentials不同的是,Resource Owner Password Credentials有了用户的参与。
Identity Server4程序中有预设的测试用户。
image.png
image.png

Identity Server 4 Config类中新增一个客户端

IdentityResource中代表能获取的身份资源。
AllowedScopes代表访问的范围。
两个必须一一对应才能获取完整的,如果有任意一方少,都不能获取到具体的信息。
注意:如果要获取其它几个预设的Scoped的话,**OpenId**是必不可少的。
如果不带OpenId而获取其它信息的话,会发出以下错误信息。
image.png
image.png
代码1.1

  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. using IdentityServer4;
  4. using IdentityServer4.Models;
  5. using System.Collections.Generic;
  6. namespace ids4
  7. {
  8. public static class Config
  9. {
  10. public static IEnumerable<IdentityResource> IdentityResources =>
  11. new IdentityResource[]
  12. {
  13. new IdentityResources.OpenId(),
  14. new IdentityResources.Profile(),
  15. new IdentityResources.Address(),
  16. new IdentityResources.Email(),
  17. new IdentityResources.Phone(),
  18. };
  19. public static IEnumerable<ApiScope> ApiScopes =>
  20. new ApiScope[]
  21. {
  22. new ApiScope("scope1","myApi"),
  23. };
  24. public static IEnumerable<Client> Clients =>
  25. new Client[]
  26. {
  27. new Client
  28. {
  29. ClientId = "console client",
  30. ClientName = "Client Credentials Client",
  31. AllowedGrantTypes = GrantTypes.ClientCredentials,
  32. ClientSecrets = { new Secret("511536EF-F270-4058-80CA-1C89C192F69A".Sha256()) },
  33. AllowedScopes =
  34. {
  35. "scope1",
  36. IdentityServerConstants.StandardScopes.OpenId
  37. }
  38. },
  39. new Client
  40. {
  41. ClientId = "winform client",
  42. ClientName = "winform debug",
  43. AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
  44. ClientSecrets = new Secret[] { new Secret("winform".Sha256()) },
  45. AllowedScopes =
  46. {
  47. "scope1",
  48. IdentityServerConstants.StandardScopes.OpenId,
  49. IdentityServerConstants.StandardScopes.Profile,
  50. IdentityServerConstants.StandardScopes.Email,
  51. IdentityServerConstants.StandardScopes.Phone,
  52. IdentityServerConstants.StandardScopes.Address
  53. }
  54. }
  55. };
  56. }
  57. }

WinForm程序代码

代码1.2

  1. using IdentityModel.Client;
  2. using System;
  3. using System.Net.Http;
  4. using System.Windows.Forms;
  5. namespace WinFormClientPassword
  6. {
  7. public partial class FrmMain : Form
  8. {
  9. private string accessToken;
  10. private DiscoveryDocumentResponse discoveryDocument;
  11. public FrmMain()
  12. {
  13. InitializeComponent();
  14. }
  15. private async void btnLogin_Click(object sender, EventArgs e)
  16. {
  17. var client = new HttpClient();
  18. discoveryDocument = await client.GetDiscoveryDocumentAsync("http://localhost:5000");
  19. var userName = txtUserName.Text;
  20. var password = txtPassword.Text;
  21. var response = await client.RequestPasswordTokenAsync(new PasswordTokenRequest
  22. {
  23. Address = discoveryDocument.TokenEndpoint,
  24. ClientId = "winform client",
  25. // 此处Scope不要也可以。 如果带上的话,必须和Identity Server4 Config对应,或者少但不能多。
  26. Scope = "scope1 openid profile address email phone",
  27. ClientSecret = "winform",
  28. UserName = userName,
  29. Password = password
  30. });
  31. if (response.IsError)
  32. {
  33. MessageBox.Show(response.Error);
  34. return;
  35. }
  36. accessToken = response.AccessToken;
  37. MessageBox.Show(response.Json.ToString());
  38. }
  39. private async void btnRequest_Click(object sender, EventArgs e)
  40. {
  41. var client = new HttpClient();
  42. client.SetBearerToken(accessToken);
  43. var response = await client.GetAsync("http://localhost:5002/identity");
  44. if (response.IsSuccessStatusCode)
  45. {
  46. MessageBox.Show(await response.Content.ReadAsStringAsync());
  47. }
  48. }
  49. private async void btnUserInfo_Click(object sender, EventArgs e)
  50. {
  51. var client = new HttpClient();
  52. client.SetBearerToken(accessToken);
  53. var response = await client.GetAsync(discoveryDocument.UserInfoEndpoint);
  54. if (response.IsSuccessStatusCode)
  55. {
  56. MessageBox.Show(await response.Content.ReadAsStringAsync());
  57. return;
  58. }
  59. MessageBox.Show(response.StatusCode.ToString());
  60. }
  61. }
  62. }

image.png

image.png