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

复制代码
<Window x:Class="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">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="70" />
            <RowDefinition Height="40" />
            <RowDefinition />
            <RowDefinition Height="40" />
            <RowDefinition />
            <RowDefinition Height="40" />
            <RowDefinition Height="70" />
        </Grid.RowDefinitions>
        <StackPanel Grid.Row="0" Margin="20" Orientation="Horizontal">
            <Label>用户名:</Label>
            <TextBox x:Name="UserNameInput" Margin="20 0" Width="150" Height="20">alice</TextBox>
            <Label>密码:</Label>
            <PasswordBox x:Name="PasswordInput" Margin="20 0" Width="150" Height="20" Password="alice"></PasswordBox>
        </StackPanel>
        <Button Grid.Row="1" Click="RequestAccessToken_ButtonClick"> 1.请求 Access Token </Button>
        <TextBox Grid.Row="2" 
                 x:Name="AccessTokenTextBlock"
                 VerticalAlignment="Stretch"
                 HorizontalAlignment="Stretch"
                 IsReadOnly="True"
                 AcceptsReturn="True"
                 AcceptsTab="True">
        </TextBox>
        <Button Grid.Row="3" Click="RequestScope1Resource_ButtonClick">2.请求 API1资源</Button>
        <TextBox Grid.Row="4"
                 x:Name="Scope1ResponseTextBlock"
                 VerticalAlignment="Stretch"
                 HorizontalAlignment="Stretch"
                 IsReadOnly="True"
                 AcceptsReturn="True"
                 AcceptsTab="True">
        </TextBox>
        <Button Grid.Row="5" Click="RequestIdentityResource_ButtonClick">3.请求 Identity 资源</Button>
        <TextBox Grid.Row="6"
                 x:Name="IdentityResponseTextBlock"
                 VerticalAlignment="Stretch"
                 HorizontalAlignment="Stretch"
                 IsReadOnly="True"
                 AcceptsReturn="True"
                 AcceptsTab="True">
        </TextBox>
    </Grid>
</Window>
View Code
复制代码

后台

复制代码
using IdentityModel.Client;
using System;
using System.Net.Http;
using System.Windows;

namespace WpfClient
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    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;
            }
        }
    }
}
View Code
复制代码

 

3.Identity配置

在Idp项目中进行配置

3.1IdentityResources配置

找到Config.cs

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

3.2Clients配置

这里也需要配置Identity资源

3.3查看测试用户(AddTestUsers)

 

4.WpfClient配置

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

 

5.运行

 

posted @   peng_boke  阅读(109)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
点击右上角即可分享
微信分享提示