.Net Core 3.0 IdentityServer4 快速入门

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

一、前言

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

    1)授权码模式

    2)简化模式

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

    4)客户端模式(client_credentials)

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

  认证步骤:

    

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

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

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

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

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

二、创建授权服务器

  

  1)安装Id4  

 

  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)看到如下发现文档算是成功的

三、创建Api资源

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

  2)安装包

  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资源

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

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

六、自定义用户验证

  在创建授权服务器的时候我们在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配置类中,修改如下:

  

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

七、通过refresh_token 获取 Token

  1)refresh_token

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

八、参考文献

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

.Net Core 3.0 IdentityServer4 快速入门02相关推荐

  1. .Net Core 3.0 IdentityServer4 快速入门

    一.简介 IdentityServer4是用于ASP.NET Core的OpenID Connect和OAuth 2.0框架. 将IdentityServer4部署到您的应用中具备如下特点: 1).认 ...

  2. 0基础快速入门CSS技术栈(4)—图解详细阐述CSS的复合选择器、标签显示模式、行高、CSS背景,及最为重要的CSS三大特性附带权重计算笔试题(附详细案例源码解析过程)

    文章目录 1. 0基础快速入门CSS技术栈(4) 2. 重点提炼 3. CSS复合选择器 3.1 后代选择器(重点) 3.1.1 example01 3.2 子元素选择器 3.2.1 exmaple0 ...

  3. openCV4.0 C++ 快速入门30讲学习笔记(自用 代码+注释)详细版

    课程来源:哔哩哔哩 环境:OpenCV4.5.1 + VS2019 目录 002.图像色彩空间转换 003.图像对象的创建与赋值 004.图像像素的读写操作 005.图像像素的算术操作(加减乘除4种不 ...

  4. Hyperledger Fabric V1.0– 开发者快速入门

    Hyperledger Fabric V1.0– 开发者快速入门 本文档演示使用Hyperledger Fabric V1.0来部署一个开发者环境并运行一个简单例子.文档包括创建和加入通道(账本).客 ...

  5. 【个人笔记】OpenCV4 C++ 快速入门 02课

    个人资料,仅供学习使用 修改时间--2022年2月6日 11:40:46 学习课程:OpenCV4 C++ 快速入门视频30讲 视频老师:贾志刚 02 图像色彩空间转换 opencv知识点: 色彩空间 ...

  6. Sers微服务快速入门-02.快速接入

    微服务给我们的第一映像是架构复杂,部署起来麻烦.其实并非如此,不同的架构选型必然带来不同的优点和缺点,没有一劳永逸的方法,配置简单是因为适用的场景面窄.在项目或产品的实际开发中往往随着时间的推进需要实 ...

  7. 探索SwitchYard 2.0.0.Alpha2快速入门

    在我的最后一篇文章中,我解释了如何在WildFly 8.1上使用SwitchYard. 同时,该项目很忙,并发布了另一个Alpha2. 这是一个很好的机会,在这里浏览快速入门并刷新您的记忆. 除了版本 ...

  8. 【自动驾驶模拟器AirSim快速入门 | 02】数据预处理:数据挖掘与准备

    这是机器未来的第16篇文章 原文首发地址:https://blog.csdn.net/RobotFutures/article/details/125321082 开源项目: 项目地址:https:/ ...

  9. Excel快速入门02

    逻辑函数 AND 判断多个条件成立 OR 判断多个条件至少有一个成立 NOT 对逻辑值求反 公式 – 逻辑函数 例:AND可以看学生所有科目成绩是否都及格 逻辑函数-IF IF,根据条件判断,然后返回 ...

最新文章

  1. 浅析I/O处理过程与存储性能的关系
  2. tablayout支持改变选中文字大小,支持左右滑动,支持viewpager,支持三角可移动指示器...
  3. ML.NET 0.8特性简介
  4. 在Ubuntu 18.04上实际安装OpenJDK 11
  5. JNI_Android项目中调用.so动态库实现详解【转】
  6. jquery自定义一个放大镜
  7. 20190819:(leetcode习题)字符串中的第一个唯一字符
  8. vim 插件 -- NERDTree
  9. gcd前缀和-蒜头君的数轴
  10. 奇迹,是为了信念牺牲一切(高策)
  11. dest是什么意思(dest是什么意思车上的)
  12. 日记app制作(OC)
  13. markdown和marktop是啥关系?
  14. 移动端Vin码识别技术发展应用
  15. EDEM-fluent耦合时出现的问题及摸索出的解决办法及DPM颗粒信息导出
  16. VS2015安装失败——系统找不到指定路径
  17. 如何创建一个linux用户名和密码,Linux下如何创建用户 | Soo Smart!
  18. WINDOWS时间服务启动失败的原因
  19. 第23课 Altium Designer20(AD20)+VESC6.4实战教程:导入嘉立创原理图 增加PCB信号层 差分线计算和走线方法(北冥有鱼
  20. codeforces - 1315C - 思维题

热门文章

  1. do...while(0)的妙用
  2. windows复制文件路径_如何在Windows 10上复制文件的完整路径
  3. cdh中使用hue使用教程_我可以在户外使用Philips Hue灯泡吗?
  4. 免杀新姿势:利用线程将恶意代码注入到内存中
  5. Highcharts数据表示(3)
  6. 顺义教委携手华平共建视频图像综合管理平台
  7. 多线程介绍和多线程模块-lock-互斥锁
  8. 【读书笔记】《编写高效的JavaScript程序》
  9. 关于商品分类 商品表和属性表的设计
  10. Blazor University (10)组件 — 捕获意外参数