新建WinForm程序

与Client Credentials不同的是,Resource Owner Password Credentials有了用户的参与。Identity Server4程序中有预设的测试用户。
Identity Server 4 Config类中新增一个客户端
IdentityResource中代表能获取的身份资源。AllowedScopes代表访问的范围。
两个必须一一对应才能获取完整的,如果有任意一方少,都不能获取到具体的信息。
注意:如果要获取其它几个预设的Scoped的话,**OpenId**是必不可少的。
如果不带OpenId而获取其它信息的话,会发出以下错误信息。

代码1.1
// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.using IdentityServer4;using IdentityServer4.Models;using System.Collections.Generic;namespace ids4{public static class Config{public static IEnumerable<IdentityResource> IdentityResources =>new IdentityResource[]{new IdentityResources.OpenId(),new IdentityResources.Profile(),new IdentityResources.Address(),new IdentityResources.Email(),new IdentityResources.Phone(),};public static IEnumerable<ApiScope> ApiScopes =>new ApiScope[]{new ApiScope("scope1","myApi"),};public static IEnumerable<Client> Clients =>new Client[]{new Client{ClientId = "console client",ClientName = "Client Credentials Client",AllowedGrantTypes = GrantTypes.ClientCredentials,ClientSecrets = { new Secret("511536EF-F270-4058-80CA-1C89C192F69A".Sha256()) },AllowedScopes ={"scope1",IdentityServerConstants.StandardScopes.OpenId}},new Client{ClientId = "winform client",ClientName = "winform debug",AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,ClientSecrets = new Secret[] { new Secret("winform".Sha256()) },AllowedScopes ={"scope1",IdentityServerConstants.StandardScopes.OpenId,IdentityServerConstants.StandardScopes.Profile,IdentityServerConstants.StandardScopes.Email,IdentityServerConstants.StandardScopes.Phone,IdentityServerConstants.StandardScopes.Address}}};}}
WinForm程序代码
代码1.2
using IdentityModel.Client;using System;using System.Net.Http;using System.Windows.Forms;namespace WinFormClientPassword{public partial class FrmMain : Form{private string accessToken;private DiscoveryDocumentResponse discoveryDocument;public FrmMain(){InitializeComponent();}private async void btnLogin_Click(object sender, EventArgs e){var client = new HttpClient();discoveryDocument = await client.GetDiscoveryDocumentAsync("http://localhost:5000");var userName = txtUserName.Text;var password = txtPassword.Text;var response = await client.RequestPasswordTokenAsync(new PasswordTokenRequest{Address = discoveryDocument.TokenEndpoint,ClientId = "winform client",// 此处Scope不要也可以。 如果带上的话,必须和Identity Server4 Config对应,或者少但不能多。Scope = "scope1 openid profile address email phone",ClientSecret = "winform",UserName = userName,Password = password});if (response.IsError){MessageBox.Show(response.Error);return;}accessToken = response.AccessToken;MessageBox.Show(response.Json.ToString());}private async void btnRequest_Click(object sender, EventArgs e){var client = new HttpClient();client.SetBearerToken(accessToken);var response = await client.GetAsync("http://localhost:5002/identity");if (response.IsSuccessStatusCode){MessageBox.Show(await response.Content.ReadAsStringAsync());}}private async void btnUserInfo_Click(object sender, EventArgs e){var client = new HttpClient();client.SetBearerToken(accessToken);var response = await client.GetAsync(discoveryDocument.UserInfoEndpoint);if (response.IsSuccessStatusCode){MessageBox.Show(await response.Content.ReadAsStringAsync());return;}MessageBox.Show(response.StatusCode.ToString());}}}


