.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

相关文章

使用Python实现快速搭建本地HTTP服务器

《使用Python实现快速搭建本地HTTP服务器》:本文主要介绍如何使用Python快速搭建本地HTTP服务器,轻松实现一键HTTP文件共享,同时结合二维码技术,让访问更简单,感兴趣的小伙伴可以了... 目录1. 概述2. 快速搭建 HTTP 文件共享服务2.1 核心思路2.2 代码实现2.3 代码解读3.

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

springboot security快速使用示例详解

《springbootsecurity快速使用示例详解》:本文主要介绍springbootsecurity快速使用示例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝... 目录创www.chinasem.cn建spring boot项目生成脚手架配置依赖接口示例代码项目结构启用s

C++快速排序超详细讲解

《C++快速排序超详细讲解》快速排序是一种高效的排序算法,通过分治法将数组划分为两部分,递归排序,直到整个数组有序,通过代码解析和示例,详细解释了快速排序的工作原理和实现过程,需要的朋友可以参考下... 目录一、快速排序原理二、快速排序标准代码三、代码解析四、使用while循环的快速排序1.代码代码1.由快

Win32下C++实现快速获取硬盘分区信息

《Win32下C++实现快速获取硬盘分区信息》这篇文章主要为大家详细介绍了Win32下C++如何实现快速获取硬盘分区信息,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 实现代码CDiskDriveUtils.h#pragma once #include <wtypesbase

Python FastAPI入门安装使用

《PythonFastAPI入门安装使用》FastAPI是一个现代、快速的PythonWeb框架,用于构建API,它基于Python3.6+的类型提示特性,使得代码更加简洁且易于绶护,这篇文章主要介... 目录第一节:FastAPI入门一、FastAPI框架介绍什么是ASGI服务(WSGI)二、FastAP

Spring AI与DeepSeek实战一之快速打造智能对话应用

《SpringAI与DeepSeek实战一之快速打造智能对话应用》本文详细介绍了如何通过SpringAI框架集成DeepSeek大模型,实现普通对话和流式对话功能,步骤包括申请API-KEY、项目搭... 目录一、概述二、申请DeepSeek的API-KEY三、项目搭建3.1. 开发环境要求3.2. mav

Python如何快速下载依赖

《Python如何快速下载依赖》本文介绍了四种在Python中快速下载依赖的方法,包括使用国内镜像源、开启pip并发下载功能、使用pipreqs批量下载项目依赖以及使用conda管理依赖,通过这些方法... 目录python快速下载依赖1. 使用国内镜像源临时使用镜像源永久配置镜像源2. 使用 pip 的并

基于.NET编写工具类解决JSON乱码问题

《基于.NET编写工具类解决JSON乱码问题》在开发过程中,我们经常会遇到JSON数据处理的问题,尤其是在数据传输和解析过程中,很容易出现编码错误导致的乱码问题,下面我们就来编写一个.NET工具类来解... 目录问题背景核心原理工具类实现使用示例总结在开发过程中,我们经常会遇到jsON数据处理的问题,尤其是

SpringBoot快速接入OpenAI大模型的方法(JDK8)

《SpringBoot快速接入OpenAI大模型的方法(JDK8)》本文介绍了如何使用AI4J快速接入OpenAI大模型,并展示了如何实现流式与非流式的输出,以及对函数调用的使用,AI4J支持JDK8... 目录使用AI4J快速接入OpenAI大模型介绍AI4J-github快速使用创建SpringBoot