IdentityServer4 资源所有者密码凭证(Resource Owner Password Credentials)



1.资源所有者密码凭证基本概念

2.创建一个wpf客户端

3.Identity配置

4.WpfClient配置

5.运行

1.资源所有者密码凭证基本概念

资源所有者密码凭证(Resource Owner Password Credentials)

资源所有者密码凭证(例如用户名和密码)直接被用来请求Access Token

通常用于遗留的凭证

资源所有者和客户端应用之间必须高度信任

其它授权方式不可用的时候才使用,尽量不用

1.1请求格式

1.2响应格式

1.3请求流程

2.创建一个wpf客户端

2.1MainWindow源码

UI

"WpfClient.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfClient"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    
        
            "70" />
            "40" />
            
            "40" />
            
            "40" />
            "70" />
        
        "0" Margin="20" Orientation="Horizontal">
            
            "UserNameInput" Margin="20 0" Width="150" Height="20">alice
            
            "PasswordInput" Margin="20 0" Width="150" Height="20" Password="alice">
        
        
        "2" 
                 x:Name="AccessTokenTextBlock"
                 VerticalAlignment="Stretch"
                 HorizontalAlignment="Stretch"
                 IsReadOnly="True"
                 AcceptsReturn="True"
                 AcceptsTab="True">
        
        
        "4"
                 x:Name="Scope1ResponseTextBlock"
                 VerticalAlignment="Stretch"
                 HorizontalAlignment="Stretch"
                 IsReadOnly="True"
                 AcceptsReturn="True"
                 AcceptsTab="True">
        
        
        "6"
                 x:Name="IdentityResponseTextBlock"
                 VerticalAlignment="Stretch"
                 HorizontalAlignment="Stretch"
                 IsReadOnly="True"
                 AcceptsReturn="True"
                 AcceptsTab="True">
        
    

后台

using IdentityModel.Client;
using System;
using System.Net.Http;
using System.Windows;

namespace WpfClient
{
    /// 
    /// Interaction logic for MainWindow.xaml
    /// 
    public partial class MainWindow : Window
    {
        private string _accessToken;
        private DiscoveryDocumentResponse _disco;
        public MainWindow()
        {
            InitializeComponent();
        }

        private async void RequestAccessToken_ButtonClick(object sender, RoutedEventArgs e)
        {
            var username = UserNameInput.Text;
            var password = PasswordInput.Password;

            // discovery endpoint
            var client = new HttpClient();
            _disco = await client.GetDiscoveryDocumentAsync("https://localhost:5001");
            if (_disco.IsError)
            {
                Console.WriteLine(_disco.Error);
                return;
            }

            // request access token
            var tokenResponse = await client.RequestPasswordTokenAsync(new PasswordTokenRequest()
            {
                Address = _disco.TokenEndpoint,
                ClientId = "wpf client",
                ClientSecret = "wpf secret",
                Scope = "scope1 openid profile email phone address",

                UserName = username,
                Password = password
            });

            if (tokenResponse.IsError)
            {
                MessageBox.Show(tokenResponse.Error);
                return;
            }
            _accessToken = tokenResponse.AccessToken;
            AccessTokenTextBlock.Text = tokenResponse.Json.ToString();
        }

        private async void RequestScope1Resource_ButtonClick(object sender, RoutedEventArgs e)
        {
            // call API     
            var apiClient = new HttpClient();
            apiClient.SetBearerToken(_accessToken);
            //var response = await apiClient.GetAsync(disco.UserInfoEndpoint);
            var response = await apiClient.GetAsync("https://localhost:6001/identity");
            if (!response.IsSuccessStatusCode)
            {
                 MessageBox.Show(response.StatusCode.ToString());
            }
            else
            {
                var content = await response.Content.ReadAsStringAsync();
                Scope1ResponseTextBlock.Text = content;
            }
        }

        private async void RequestIdentityResource_ButtonClick(object sender, RoutedEventArgs e)
        {
            // call Identity Resource from Identity Server
            var apiClient = new HttpClient();
            apiClient.SetBearerToken(_accessToken);
            var response = await apiClient.GetAsync(_disco.UserInfoEndpoint);         
            if (!response.IsSuccessStatusCode)
            {
                MessageBox.Show(response.StatusCode.ToString());
            }
            else
            {
                var content = await response.Content.ReadAsStringAsync();
                IdentityResponseTextBlock.Text = content;
            }
        }
    }
}

3.Identity配置

在Idp项目中进行配置

3.1IdentityResources配置

找到Config.cs

这里为了可以更多的访问Identity资源,把email phone address 都配置上

3.2Clients配置

这里也需要配置Identity资源

3.3查看测试用户(AddTestUsers)

4.WpfClient配置

客户端需要配置用户名密码以及需要访问的Identity资源

5.运行