.Net Core 3.0 IdentityServer4 快速入门02

2023-11-06 09:48

本文主要是介绍.Net Core 3.0 IdentityServer4 快速入门02,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

640?wx_fmt=gif

.Net Core 3.0 IdentityServer4 快速入门

              —— resource owner password credentials(密码模式)

一、前言

  OAuth2.0默认有四种授权模式(GrantType):

    1)授权码模式

    2)简化模式

    3)密码模式(resource owner password credentials)

    4)客户端模式(client_credentials)

  上一小节 接受了 客户端模式 ,本小节将介绍 密码模式,OAuth2.0资源所有者密码授权功能允许客户端将用户名和密码发送到授权服务器,并获得该用户的访问令牌

  认证步骤:

    640?wx_fmt=png

    1)用户将用户名和密码提供给客户端

    2)客户端再将用户名和密码发送给授权服务器(Id4)请求令牌

    3)授权服务器(Id4)验证用户的有效性,返回给客户端令牌

    4)Api资源收到第一个(首次)请求之后,会到授权服务器(Id4)获取公钥,然后用公钥验证Token是否合法,如果合法将进行后面的有效性验证,后面的请求都会用首次请求的公钥来验证(jwt去中心化验证的思想)

    Resource Owner 其实就是User,密码模式相较于客户端模式,多了一个参与者,就是User,通过User的用户名和密码向Identity Server 申请访问令牌,这种模式下要求客户端不得存储密码,但我们并不能确保客户端是否存储了密码,所以该模式仅仅适用于受信任的客户端。因此该模式不推荐使用

二、创建授权服务器

  640?wx_fmt=png

   1)安装Id4  

640?wx_fmt=png 

  2)创建一个Config类模拟配置要保护的资源和可以访问的api客户端服务器

using IdentityServer4;	
using IdentityServer4.Models;	
using IdentityServer4.Test;	
using System.Collections.Generic;	namespace IdentityServer02	
{	public static class Config	{	/// <summary>	/// 需要保护的api资源	/// </summary>	public static IEnumerable<ApiResource> Apis =>	new List<ApiResource>	{	new ApiResource("api1","My Api")	};	public static IEnumerable<Client> Clients =>	new List<Client>	{	//客户端	new Client	{	ClientId="client",	ClientSecrets={ new Secret("aju".Sha256())},	AllowedGrantTypes=GrantTypes.ResourceOwnerPassword,	//如果要获取refresh_tokens ,必须在scopes中加上OfflineAccess	AllowedScopes={ "api1", IdentityServerConstants.StandardScopes.OfflineAccess},	AllowOfflineAccess=true	}	};	public static List<TestUser> Users = new List<TestUser>	{	new TestUser	{	SubjectId="001",	Password="Aju_001",	Username="Aju_001"	},	new TestUser	{	SubjectId="002",	Password="Aju_002",	Username="Aju_002"	}	};	}	
}

与客户端模式不一致的地方就在于(AllowedGrantTypes=GrantTypes.ResourceOwnerPassword)此处设置为资源所有者(密码模式)

  3)配置StartUp

using Microsoft.AspNetCore.Builder;	
using Microsoft.AspNetCore.Hosting;	
using Microsoft.Extensions.DependencyInjection;	
using Microsoft.Extensions.Hosting;	namespace IdentityServer02	
{	public class Startup	{	// This method gets called by the runtime. Use this method to add services to the container.	// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940	public void ConfigureServices(IServiceCollection services)	{	var builder = services.AddIdentityServer()	.AddInMemoryApiResources(Config.Apis)	.AddInMemoryClients(Config.Clients)	.AddTestUsers(Config.Users);19             builder.AddDeveloperSigningCredential();	}	// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.	public void Configure(IApplicationBuilder app, IWebHostEnvironment env)	{	if (env.IsDevelopment())	{	app.UseDeveloperExceptionPage();	}	// app.UseRouting();	app.UseIdentityServer();	}	}	
}

5)验证配置是否成功

  在浏览器中输入(http://localhost:5000/.well-known/openid-configuration)看到如下发现文档算是成功的

640?wx_fmt=png

 三、创建Api资源

  1)步骤如创建授权服务的1)

  2)安装包

640?wx_fmt=png

   3)创建一个受保护的ApiController

using Microsoft.AspNetCore.Authorization;	
using Microsoft.AspNetCore.Mvc;	
using System.Linq;	namespace Api02.Controllers	
{	[Route("Api")]	[Authorize]	public class ApiController : ControllerBase	{	public IActionResult Get()	{	return new JsonResult(from c in User.Claims select new { c.Type, c.Value });	}	}	
}

4)配置StartUp

using Microsoft.AspNetCore.Builder;	
using Microsoft.AspNetCore.Hosting;	
using Microsoft.Extensions.Configuration;	
using Microsoft.Extensions.DependencyInjection;	
using Microsoft.Extensions.Hosting;	namespace Api02	
{	public class Startup	{	public Startup(IConfiguration configuration)	{	Configuration = configuration;	}	public IConfiguration Configuration { get; }	// This method gets called by the runtime. Use this method to add services to the container.	public void ConfigureServices(IServiceCollection services)	{	services.AddControllers();	services.AddAuthentication("Bearer").AddJwtBearer("Bearer", options =>	{	options.Authority = "http://localhost:5000";	options.RequireHttpsMetadata = false;	options.Audience = "api1";	});	}	// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.	public void Configure(IApplicationBuilder app, IWebHostEnvironment env)	{	if (env.IsDevelopment())	{	app.UseDeveloperExceptionPage();	}	app.UseRouting();	app.UseAuthentication();//认证	app.UseAuthorization();//授权	app.UseEndpoints(endpoints =>	{	endpoints.MapControllers();	});	}	}	
}

四、创建客户端(控制台 模拟客户端)

using IdentityModel.Client;	
using Newtonsoft.Json.Linq;	
using System;	
using System.Net.Http;	
using System.Threading.Tasks;	namespace Client02	
{	class Program	{	static async Task Main(string[] args)	{	// Console.WriteLine("Hello World!");	var client = new HttpClient();	var disco = await client.GetDiscoveryDocumentAsync("http://localhost:5000");	if (disco.IsError)	{	Console.WriteLine(disco.Error);	return;	}	var tokenResponse = await client.RequestPasswordTokenAsync(	new PasswordTokenRequest	{	Address = disco.TokenEndpoint,	ClientId = "client",	ClientSecret = "aju",	Scope = "api1 offline_access",	UserName = "Aju",	Password = "Aju_password"	});	if (tokenResponse.IsError)	{	Console.WriteLine(tokenResponse.Error);	return;	}	Console.WriteLine(tokenResponse.Json);	Console.WriteLine("\n\n");	//call api	var apiClient = new HttpClient();	apiClient.SetBearerToken(tokenResponse.AccessToken);	var response = await apiClient.GetAsync("http://localhost:5001/api");	if (!response.IsSuccessStatusCode)	{	Console.WriteLine(response.StatusCode);	}	else	{	var content = await response.Content.ReadAsStringAsync();	Console.WriteLine(JArray.Parse(content));	}	Console.ReadLine();	}	}	
}

五、验证

  1)直接获取Api资源

640?wx_fmt=png

  出现了401未授权提示,这就说明我们的Api需要授权

  2)运行客户端访问Api资源

640?wx_fmt=png

六、自定义用户验证

  在创建授权服务器的时候我们在Config中默认模拟(写死)两个用户,这显得有点不太人性化,那我们就来自定义验证用户信息

  1)创建 自定义 验证 类 ResourceOwnerValidator 

using IdentityModel;	
using IdentityServer4.Models;	
using IdentityServer4.Validation;	
using System.Threading.Tasks;	namespace IdentityServer02	
{	public class ResourceOwnerValidator : IResourceOwnerPasswordValidator	{	public Task ValidateAsync(ResourceOwnerPasswordValidationContext context)	{	if (context.UserName == "Aju" && context.Password == "Aju_password")	{	context.Result = new GrantValidationResult(	subject: context.UserName,	authenticationMethod: OidcConstants.AuthenticationMethods.Password);	}	else	{	context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "无效的秘钥");	}	return Task.FromResult("");	}	}	
}

2)在授权服务器StartUp配置类中,修改如下:

  640?wx_fmt=png

    3)在客户端中将 用户名 和 密码 修改成 我们在自定义 用户 验证类 中写的用户名和密码,进行测试

七、通过refresh_token 获取 Token

  1)refresh_token 

    获取请求授权后会返回 access_token、expire_in、refresh_token 等内容,每当access_token 失效后用户需要重新授权,但是有了refresh_token后,客户端(Client)检测到Token失效后可以直接通过refresh_token向授权服务器申请新的token

640?wx_fmt=png

八、参考文献

  http://docs.identityserver.io/en/latest/index.html

640?wx_fmt=gif 

640?wx_fmt=jpeg

这篇关于.Net Core 3.0 IdentityServer4 快速入门02的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/355877

相关文章

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

电脑桌面文件删除了怎么找回来?别急,快速恢复攻略在此

在日常使用电脑的过程中,我们经常会遇到这样的情况:一不小心,桌面上的某个重要文件被删除了。这时,大多数人可能会感到惊慌失措,不知所措。 其实,不必过于担心,因为有很多方法可以帮助我们找回被删除的桌面文件。下面,就让我们一起来了解一下这些恢复桌面文件的方法吧。 一、使用撤销操作 如果我们刚刚删除了桌面上的文件,并且还没有进行其他操作,那么可以尝试使用撤销操作来恢复文件。在键盘上同时按下“C

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

4B参数秒杀GPT-3.5:MiniCPM 3.0惊艳登场!

​ 面壁智能 在 AI 的世界里,总有那么几个时刻让人惊叹不已。面壁智能推出的 MiniCPM 3.0,这个仅有4B参数的"小钢炮",正在以惊人的实力挑战着 GPT-3.5 这个曾经的AI巨人。 MiniCPM 3.0 MiniCPM 3.0 MiniCPM 3.0 目前的主要功能有: 长上下文功能:原生支持 32k 上下文长度,性能完美。我们引入了

数论入门整理(updating)

一、gcd lcm 基础中的基础,一般用来处理计算第一步什么的,分数化简之类。 LL gcd(LL a, LL b) { return b ? gcd(b, a % b) : a; } <pre name="code" class="cpp">LL lcm(LL a, LL b){LL c = gcd(a, b);return a / c * b;} 例题:

Java 创建图形用户界面(GUI)入门指南(Swing库 JFrame 类)概述

概述 基本概念 Java Swing 的架构 Java Swing 是一个为 Java 设计的 GUI 工具包,是 JAVA 基础类的一部分,基于 Java AWT 构建,提供了一系列轻量级、可定制的图形用户界面(GUI)组件。 与 AWT 相比,Swing 提供了许多比 AWT 更好的屏幕显示元素,更加灵活和可定制,具有更好的跨平台性能。 组件和容器 Java Swing 提供了许多

【IPV6从入门到起飞】5-1 IPV6+Home Assistant(搭建基本环境)

【IPV6从入门到起飞】5-1 IPV6+Home Assistant #搭建基本环境 1 背景2 docker下载 hass3 创建容器4 浏览器访问 hass5 手机APP远程访问hass6 更多玩法 1 背景 既然电脑可以IPV6入站,手机流量可以访问IPV6网络的服务,为什么不在电脑搭建Home Assistant(hass),来控制你的设备呢?@智能家居 @万物互联

如何在Visual Studio中调试.NET源码

今天偶然在看别人代码时,发现在他的代码里使用了Any判断List<T>是否为空。 我一般的做法是先判断是否为null,再判断Count。 看了一下Count的源码如下: 1 [__DynamicallyInvokable]2 public int Count3 {4 [__DynamicallyInvokable]5 get

2、PF-Net点云补全

2、PF-Net 点云补全 PF-Net论文链接:PF-Net PF-Net (Point Fractal Network for 3D Point Cloud Completion)是一种专门为三维点云补全设计的深度学习模型。点云补全实际上和图片补全是一个逻辑,都是采用GAN模型的思想来进行补全,在图片补全中,将部分像素点删除并且标记,然后卷积特征提取预测、判别器判别,来训练模型,生成的像

poj 2104 and hdu 2665 划分树模板入门题

题意: 给一个数组n(1e5)个数,给一个范围(fr, to, k),求这个范围中第k大的数。 解析: 划分树入门。 bing神的模板。 坑爹的地方是把-l 看成了-1........ 一直re。 代码: poj 2104: #include <iostream>#include <cstdio>#include <cstdlib>#include <al