ASP.NET Core3.1使用IdentityServer4中间件系列随笔(四):创建使用[ResourceOwnerPassword-资源所有者密码凭证]授权模式的客户端
配套源码:https://gitee.com/jardeng/IdentitySolution
本篇将创建使用[ResourceOwnerPassword-资源所有者密码凭证]授权模式的客户端,来对受保护的API资源进行访问。
接上一篇项目,在IdentityServer项目Config.cs中添加一个客户端
/// 资源所有者密码凭证(ResourceOwnerPassword)
/// Resource Owner其实就是User,所以可以直译为用户名密码模式。
/// 密码模式相较于客户端凭证模式,多了一个参与者,就是User。
/// 通过User的用户名和密码向Identity Server申请访问令牌。
new Client
{
ClientId = "client1",
AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
ClientSecrets = { new Secret("secret".Sha256()) },
AllowedScopes = { "api1" }
}
再添加一个用户的集合(测试数据来自IdentityServer官方)。
完整的Config.cs代码
using System.Collections.Generic;
using System.Security.Claims; using IdentityModel; using IdentityServer4.Models;
using IdentityServer4.Test; namespace IdentityServer
{
/// <summary>
/// IdentityServer资源和客户端配置文件
/// </summary>
public static class Config
{
/// <summary>
/// API资源集合
/// 如果您将在生产环境中使用此功能,那么给您的API取一个逻辑名称就很重要。
/// 开发人员将使用它通过身份服务器连接到您的api。
/// 它应该以简单的方式向开发人员和用户描述您的api。
/// </summary>
public static IEnumerable<ApiResource> Apis => new List<ApiResource> { new ApiResource("api1", "My API") }; /// <summary>
/// 客户端集合
/// </summary>
public static IEnumerable<Client> Clients =>
new List<Client>
{
/// 客户端模式(Client Credentials)
/// 可以将ClientId和ClientSecret视为应用程序本身的登录名和密码。
/// 它将您的应用程序标识到身份服务器,以便它知道哪个应用程序正在尝试与其连接。
new Client
{
//客户端标识
ClientId = "client",
//没有交互用户,使用clientid/secret进行身份验证,适用于和用户无关,机器与机器之间直接交互访问资源的场景。
AllowedGrantTypes = GrantTypes.ClientCredentials,
//认证密钥
ClientSecrets = { new Secret("secret".Sha256()) },
//客户端有权访问的作用域
AllowedScopes = { "api1" }
},
/// 资源所有者密码凭证(ResourceOwnerPassword)
/// Resource Owner其实就是User,所以可以直译为用户名密码模式。
/// 密码模式相较于客户端凭证模式,多了一个参与者,就是User。
/// 通过User的用户名和密码向Identity Server申请访问令牌。
new Client
{
ClientId = "client1",
AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
ClientSecrets = { new Secret("secret".Sha256()) },
AllowedScopes = { "api1" }
}
}; /// <summary>
/// 用户集合
/// </summary>
public static List<TestUser> Users =>
new List<TestUser>
{
new TestUser{SubjectId = "", Username = "alice", Password = "alice",
Claims =
{
new Claim(JwtClaimTypes.Name, "Alice Smith"),
new Claim(JwtClaimTypes.GivenName, "Alice"),
new Claim(JwtClaimTypes.FamilyName, "Smith"),
new Claim(JwtClaimTypes.Email, "AliceSmith@email.com"),
new Claim(JwtClaimTypes.EmailVerified, "true", ClaimValueTypes.Boolean),
new Claim(JwtClaimTypes.WebSite, "http://alice.com"),
new Claim(JwtClaimTypes.Address, @"{ 'street_address': 'One Hacker Way', 'locality': 'Heidelberg', 'postal_code': 69118, 'country': 'Germany' }", IdentityServer4.IdentityServerConstants.ClaimValueTypes.Json)
}
},
new TestUser{SubjectId = "", Username = "bob", Password = "bob",
Claims =
{
new Claim(JwtClaimTypes.Name, "Bob Smith"),
new Claim(JwtClaimTypes.GivenName, "Bob"),
new Claim(JwtClaimTypes.FamilyName, "Smith"),
new Claim(JwtClaimTypes.Email, "BobSmith@email.com"),
new Claim(JwtClaimTypes.EmailVerified, "true", ClaimValueTypes.Boolean),
new Claim(JwtClaimTypes.WebSite, "http://bob.com"),
new Claim(JwtClaimTypes.Address, @"{ 'street_address': 'One Hacker Way', 'locality': 'Heidelberg', 'postal_code': 69118, 'country': 'Germany' }", IdentityServer4.IdentityServerConstants.ClaimValueTypes.Json),
new Claim("location", "somewhere")
}
}
};
}
}
我们使用Postman来获取ResourceOwnerPassword这种模式的AcceccToken
与上一种 Client Credentials 模式不同的是 client_id 使用 client1,grant_type 由原来的 client_credentials 改为 password,多了 username 和 password 两个参数,使用用户名密码 alice / alice 来登录
2、创建一个名为 ResourceOwnerPasswordConsoleApp 的控制台客户端应用。
创建完成后的项目截图
3、添加nuget包:IdentityModel
在Program.cs编写代码
using System;
using System.Net.Http;
using System.Threading.Tasks; using IdentityModel.Client; using Newtonsoft.Json.Linq; namespace ResourceOwnerPasswordConsoleApp
{
class Program
{
static async Task Main(string[] args)
{
bool verifySuccess = false;
TokenResponse tokenResponse = null;
while (!verifySuccess)
{
Console.WriteLine("请输入用户名:");
string userName = Console.ReadLine();
Console.WriteLine("请输入密码:");
string password = Console.ReadLine(); //discovery endpoint - 发现终结点
HttpClient client = new HttpClient();
DiscoveryDocumentResponse disco = await client.GetDiscoveryDocumentAsync("http://localhost:5000");
if (disco.IsError)
{
Console.WriteLine($"[DiscoveryDocumentResponse Error]: {disco.Error}");
return;
} //request assess token - 请求访问令牌
tokenResponse = await client.RequestPasswordTokenAsync(new PasswordTokenRequest
{
Address = disco.TokenEndpoint,
ClientId = "client1",
ClientSecret = "secret",
Scope = "api1",
UserName = userName,
Password = password
});
if (tokenResponse.IsError)
{
//ClientId 与 ClientSecret 错误,报错:invalid_client
//Scope 错误,报错:invalid_scope
//UserName 与 Password 错误,报错:invalid_grant
string errorDesc = tokenResponse.ErrorDescription;
if (string.IsNullOrEmpty(errorDesc)) errorDesc = "";
if (errorDesc.Equals("invalid_username_or_password"))
{
Console.WriteLine("用户名或密码错误,请重新输入!");
}
else
{
Console.WriteLine($"[TokenResponse Error]: {tokenResponse.Error}, [TokenResponse Error Description]: {errorDesc}");
}
Console.WriteLine("");
continue;
}
else
{
Console.WriteLine("");
Console.WriteLine($"Access Token: {tokenResponse.AccessToken}");
verifySuccess = true;
}
} //call API Resource - 访问API资源
HttpClient apiClient = new HttpClient();
apiClient.SetBearerToken(tokenResponse?.AccessToken);
HttpResponseMessage response = await apiClient.GetAsync("http://localhost:6000/weatherforecast");
if (!response.IsSuccessStatusCode)
{
Console.WriteLine($"API Request Error, StatusCode is : {response.StatusCode}");
}
else
{
string content = await response.Content.ReadAsStringAsync();
Console.WriteLine("");
Console.WriteLine($"Result: {JArray.Parse(content)}");
} Console.ReadKey();
}
}
}
用户名密码错误的话,会一直提示重新输入
我们使用用户名密码 alice / alice 进行登录
可以看到,成功获取到AccessToken,并使用AccessToken访问到受保护的API获取到结果。
ASP.NET Core3.1使用IdentityServer4中间件系列随笔(四):创建使用[ResourceOwnerPassword-资源所有者密码凭证]授权模式的客户端的更多相关文章
- ASP.NET Core3.1使用IdentityServer4中间件系列随笔(三):创建使用[ClientCredentials客户端凭证]授权模式的客户端
配套源码:https://gitee.com/jardeng/IdentitySolution 上一篇<ASP.NET Core3.1使用IdentityServer4中间件系列随笔(二):创建 ...
- ASP.NET Core3.1使用IdentityServer4中间件系列随笔(二):创建API项目,配置IdentityServer保护API资源
配套源码:https://gitee.com/jardeng/IdentitySolution 接上一篇<ASP.NET Core3.1使用IdentityServer4中间件系列随笔(一):搭 ...
- ASP.NET Core3.1使用IdentityServer4中间件系列随笔(五):创建使用[Code-授权码]授权模式的客户端
配套源码:https://gitee.com/jardeng/IdentitySolution 本篇将创建使用[Code-授权码]授权模式的客户端,来对受保护的API资源进行访问. 1.接上一篇项目, ...
- ASP.NET Core3.1使用IdentityServer4中间件系列随笔(一):搭建认证服务器
配套源码:https://gitee.com/jardeng/IdentitySolution 1.创建ASP.NET Core Web应用程序,选择空模板. 去掉HTTPS 2.添加nuget包:I ...
- IdentityServer4(8)- 使用密码认证方式控制API访问(资源所有者密码授权模式)
一.前言 本文已经更新到 .NET Core 2.2 OAuth 2.0 资源所有者密码模式允许客户端向令牌服务发送用户名和密码,并获取代表该用户的访问令牌. 除了通过无法浏览器进行交互的应用程序之外 ...
- IdentityServer4系列 | 资源密码凭证模式
一.前言 从上一篇关于客户端凭证模式中,我们通过创建一个认证授权访问服务,定义一个API和要访问它的客户端,客户端通过IdentityServer上请求访问令牌,并使用它来控制访问API.其中,我们也 ...
- asp.net core IdentityServer4 实现 resource owner password credentials(密码凭证)
前言 OAuth 2.0默认四种授权模式(GrantType) 授权码模式(authorization_code) 简化模式(implicit) 密码模式(resource owner passwor ...
- 认证授权:IdentityServer4 - 各种授权模式应用
前言: 前面介绍了IdentityServer4 的简单应用,本篇将继续讲解IdentityServer4 的各种授权模式使用示例 授权模式: 环境准备 a)调整项目结构如下: b)调整cz.Id ...
- 探索Asp net core3中的 项目文件、Program.cs和通用host(译)
引言 原文地址 在这篇博客中我将探索一些关于Asp.net core 3.0应用的基础功能--.csproj 项目文件和Program源文件.我将会描述他们从asp.net core 2.X在默认模版 ...
随机推荐
- 3.29省选模拟赛 除法与取模 dp+组合计数
LINK:除法与取模 鬼题.不过50分很好写.考虑不带除法的时候 其实是一个dp的组合计数. 考虑带除法的时候需要状压一下除法操作. 因为除法操作是不受x的大小影响的 所以要状压这个除法操作. 直接采 ...
- 类加载Class Loading
JVM 何时.如何把 Class 文件加载到内存,形成可以直接使用的 Java 类型,并开始执行代码? 类的生命周期 加载 - 连接(验证.准备.解析)- 初始化 - 使用 - 卸载. 注意,加载 ...
- python网络爬虫实战PDF高清完整版免费下载|百度云盘|Python基础教程免费电子书
点击获取提取码:vg1y python网络爬虫实战帮助读者学习Python并开发出符合自己要求的网络爬虫.网络爬虫,又被称为网页蜘蛛,网络机器人,是一种按照一定的规则,自动地抓取互联网信息的程序或者脚 ...
- LeetCode 算法 | 如何拆分数组?
题目: 给定长度为 2n 的数组, 你的任务是将这些数分成 n 对, 例如 (a1, b1), (a2, b2), ..., (an, bn) ,使得从1 到 n 的 min(ai, bi) 总和最大 ...
- canvas小画板--(1)平滑曲线
功能需求 项目需求:需要实现一个可以自由书写的小画板 简单实现 对于熟悉canvas的同学来说,这个需求很简单,短短几十行代码就能实现: <!doctype html> <html& ...
- “随手记”开发记录day12
就我们团队昨天的讨论,今天进行更改. 今天我们先简单的更改了之前的粉色背景图,因为用户反应总览界面的“总览”二字,是深粉色背景不太美观.进过多次更改之后使颜色变得更舒适.
- Java 命令行 编译、执行、打包
Java 命令行 编译.执行.打包 一般来说 IDE 能够很方便的编译打包. 我写这篇文章是遇到了不能使用 IDE 的情况,简单记录一下,不做深入探讨. 环境 linux jdk 1.8 简单的编译执 ...
- Python3 连接 Oracle 数据库
Python3 连接 Oracle 数据库 需要导出一些稍微复杂的数据,用Python处理很方便 环境 Win10 Python 3.7.0 Oracle 11g 安装依赖 安装 cx_Oracle ...
- 基于Logistic回归和sigmoid函数的分类算法推导
此部分内容是对机器学习实战一书的第五章的数学推导,主要是对5.2节代码实现中,有一部分省去了相关的公式推导,这里进行了推导,后续会将算法进行java实现.此部分同样因为公式较多,采用手写推导,拍照记录 ...
- JavaFX桌面应用-MVC模式开发,“真香”
使用mvc模块开发JavaFX桌面应用在JavaFX系列文章第一篇 JavaFX桌面应用开发-HelloWorld 已经提到过,这里单独整理使用mvc模式开发开发的流程. ~ JavaFX桌面应用开发 ...