.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

相关文章

C#使用Spire.Doc for .NET实现HTML转Word的高效方案

《C#使用Spire.Docfor.NET实现HTML转Word的高效方案》在Web开发中,HTML内容的生成与处理是高频需求,然而,当用户需要将HTML页面或动态生成的HTML字符串转换为Wor... 目录引言一、html转Word的典型场景与挑战二、用 Spire.Doc 实现 HTML 转 Word1

从入门到精通详解Python虚拟环境完全指南

《从入门到精通详解Python虚拟环境完全指南》Python虚拟环境是一个独立的Python运行环境,它允许你为不同的项目创建隔离的Python环境,下面小编就来和大家详细介绍一下吧... 目录什么是python虚拟环境一、使用venv创建和管理虚拟环境1.1 创建虚拟环境1.2 激活虚拟环境1.3 验证虚

Python多线程实现大文件快速下载的代码实现

《Python多线程实现大文件快速下载的代码实现》在互联网时代,文件下载是日常操作之一,尤其是大文件,然而,网络条件不稳定或带宽有限时,下载速度会变得很慢,本文将介绍如何使用Python实现多线程下载... 目录引言一、多线程下载原理二、python实现多线程下载代码说明:三、实战案例四、注意事项五、总结引

C#使用Spire.XLS快速生成多表格Excel文件

《C#使用Spire.XLS快速生成多表格Excel文件》在日常开发中,我们经常需要将业务数据导出为结构清晰的Excel文件,本文将手把手教你使用Spire.XLS这个强大的.NET组件,只需几行C#... 目录一、Spire.XLS核心优势清单1.1 性能碾压:从3秒到0.5秒的质变1.2 批量操作的优雅

Java List 使用举例(从入门到精通)

《JavaList使用举例(从入门到精通)》本文系统讲解JavaList,涵盖基础概念、核心特性、常用实现(如ArrayList、LinkedList)及性能对比,介绍创建、操作、遍历方法,结合实... 目录一、List 基础概念1.1 什么是 List?1.2 List 的核心特性1.3 List 家族成

Go语言使用net/http构建一个RESTful API的示例代码

《Go语言使用net/http构建一个RESTfulAPI的示例代码》Go的标准库net/http提供了构建Web服务所需的强大功能,虽然众多第三方框架(如Gin、Echo)已经封装了很多功能,但... 目录引言一、什么是 RESTful API?二、实战目标:用户信息管理 API三、代码实现1. 用户数据

在ASP.NET项目中如何使用C#生成二维码

《在ASP.NET项目中如何使用C#生成二维码》二维码(QRCode)已广泛应用于网址分享,支付链接等场景,本文将以ASP.NET为示例,演示如何实现输入文本/URL,生成二维码,在线显示与下载的完整... 目录创建前端页面(Index.cshtml)后端二维码生成逻辑(Index.cshtml.cs)总结

Mybatis-Plus 3.5.12 分页拦截器消失的问题及快速解决方法

《Mybatis-Plus3.5.12分页拦截器消失的问题及快速解决方法》作为Java开发者,我们都爱用Mybatis-Plus简化CRUD操作,尤其是它的分页功能,几行代码就能搞定复杂的分页查询... 目录一、问题场景:分页拦截器突然 “失踪”二、问题根源:依赖拆分惹的祸三、解决办法:添加扩展依赖四、分页

c++日志库log4cplus快速入门小结

《c++日志库log4cplus快速入门小结》文章浏览阅读1.1w次,点赞9次,收藏44次。本文介绍Log4cplus,一种适用于C++的线程安全日志记录API,提供灵活的日志管理和配置控制。文章涵盖... 目录简介日志等级配置文件使用关于初始化使用示例总结参考资料简介log4j 用于Java,log4c

史上最全MybatisPlus从入门到精通

《史上最全MybatisPlus从入门到精通》MyBatis-Plus是MyBatis增强工具,简化开发并提升效率,支持自动映射表名/字段与实体类,提供条件构造器、多种查询方式(等值/范围/模糊/分页... 目录1.简介2.基础篇2.1.通用mapper接口操作2.2.通用service接口操作3.进阶篇3