一 、前言

从上一篇关于 常见术语说明中,主要是对IdentityServer4的说明,以及其中涉及常见的术语的表述说明,包括对身份认证服务器、用户、客户端、资源以及各个令牌等进行对比区别说明。

而在这一篇中,我们将尝试通过简单的方式来搭一个我们的IdentityServer授权服务器,熟悉IdentityServer4中搭建的流程以及将出现的问题。

二、 搭建

以下的项目示例都是基于IdentityServer4 4.x版本以上进行说明。

4.x版本较之前3.x的版本都有一些变更,在本例中,若发现与3.x版本有变更的一些地方,都会进行记录说明。

2.1.创建项目

建立一个空的Asp.Net Core项目 ,使用Empty空模板

2.2.安装配置

2.2.1. 安装程序包

  • 可通过命令行的方式

    NuGet>Install-Package IdentityServer4  

  • 通过包管理器方式

    添加IdentityServer4包

2.2.2. 配置管道

修改Configure方法,注入到容器

 app.UseIdentityServer();

2.2.3. 配置内容

将服务注入到容器后,还需要对IdentityServce进行配置内容

  • 哪些API需要Authorization Server进行资源保护
  • 哪些Client可以使用这个Authorization Server
  • 哪些User可以被这个AuthorizationServer识别并授权
  • 哪些资源可以指定作用域

这里方便演示,直接以静态化的形式展示,实际开发应用中,可结合数据库或reidis缓存的数据持久化方式获取。

建立配置内容文件 IdentityConfig.cs(具体的 OpenID Connect 配置信息来源文件)

    public class IdentityConfig
{
public static IEnumerable<IdentityResource> IdentityResources =>
new IdentityResource[]
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
};
/// <summary>
/// Authorization Server保护了哪些 API Scope(作用域)
/// </summary>
/// <returns></returns>
public static IEnumerable<ApiScope> GetApiScopes()
{
return new[] { new ApiScope("ApiScope1", "ApiScope2") };
}
/// <summary>
/// 哪些客户端 Client(应用) 可以使用这个 Authorization Server
/// </summary>
/// <returns></returns>
public static IEnumerable<Client> GetClients()
{
return new[]
{
new Client()
{
ClientId="YuanIdentity", ///客户端的标识,要是惟一的
ClientSecrets=new []{new Secret("6KGqzUx6nfZZp0a4NH2xenWSJQWAT8la".Sha256())}, ////客户端密码,进行了加密
AllowedGrantTypes= GrantTypes.ClientCredentials, ////授权方式,这里采用的是客户端认证模式,只要ClientId,以及ClientSecrets正确即可访问对应的AllowedScopes里面的api资源
AllowedScopes=new[]{"ApiScope1" }, //定义这个客户端可以访问的APi资源数组,上面只有一个api }
};
}
/// <summary>
/// 哪些User可以被这个AuthorizationServer识别并授权
/// </summary>
/// <returns></returns>
public static IEnumerable<TestUser> GetTestUsers()
{
return new[]
{
new TestUser
{
SubjectId="001",
Username="i3yuan",
Password="123456"
}
};
} }

注意,如果你的代码没问题,但是依然报错,比如“无效的scope”等,就可能是nuget包版本问题

在3.1.x 到 4.x 的变更中,ApiResourceScope 正式独立出来为 ApiScope 对象,区别ApiResourceScope的关系, Scope 是属于 ApiResource 的一个属性,可以包含多个 Scope

所以

在3.x版本中

 public static IEnumerable<ApiResource> GetApiResources()
{
return new[] { new ApiResource("ApiScope1", "ApiScope2") };
}

改成4.x版本为

public static IEnumerable<ApiScope> GetApiScopes()
{
return new[] { new ApiScope("ApiScope1", "ApiScope2") };
}

2.2.4. 添加配置服务

在Startup.cs文件,ConfigureServices方法中

        public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddIdentityServer()
.AddDeveloperSigningCredential() //开发环境
.AddTestUsers(IdentityConfig.GetTestUsers().ToList())
.AddInMemoryClients(IdentityConfig.GetClients())
.AddInMemoryApiScopes(IdentityConfig.GetApiScopes());
services.AddControllers();
}

1. 在学习 IdentityServer4 时熟悉的 InMemory 来说,AddInMemoryApiResources 变为了 AddInMemoryApiScopes 这个 ApiScope

2. 我们现在是本地调试,可以告诉identity server4在程序的运行时候对这项工作进行设定: AddDeveloperSigningCredential(),它默认会存到硬盘上的, 所以每次重启服务不会破坏开发时的数据同步。这个方法只适合用于identity server4在单个机器运行, 如果是 production 你得使用AddSigningCredential()这个方法

以上操作完成后, 启动项目,通过它的 .well-known 端点来访问服务器的配置信息,在浏览器的地址栏中,输入地址:http://localhost:5050/.well-known/openid-configuration,并回车。应该可以看到如下的响应信息。

2.3. 获取token

2.3.1. 启动项目

2.3.2. 测试访问地址

http://localhost:5050/connect/token

body参数 application/x-www-form-urlencoded (post)

2.3.3. Access_Token

需要对token进行签名, 这意味着 identity server 需要一对public和private key。同时也是可以由上图的解析发现是需要一对公私key的。

三、UI界面

考虑IdentityServer4需要进行管理查看,添加页面管理界面

官方为我们提供了一个快速启动的UI界面,我们只需要下载下来即可,这里有两个方法:

3.1. QuickStart UI界面

1、直接从这个地址下来下载,拷贝到项目中,一共三个文件夹;// https://github.com/IdentityServer/IdentityServer4.Quickstart.UI

2、在当前文件夹中执行命令,自动下载;

iex ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/IdentityServer/IdentityServer4.Quickstart.UI/master/getmaster.ps1'))

3.2. 默认目录

下载完官方提供的默认UI界面后,会提供默认的三个目录文件夹分别为:Quickstart (控制器方法)、Views(视图)、wwwroot (静态文件)

3.3. 修改配置

配置中间件来使用静态文件:

app.UseStaticFiles();

四、运行

运行展示效果,启动默认的地址如下:

http://localhost:5050

运行项目后,可以发现启动默认的欢迎界面,看到对应的项目版本,我们这里用的是最新的IdentityServer4版本为4.1.1 ,以及点击 discovery document,可以看到了我们上边说到的 token 获取的接口地址 ,其中对应的端点地址信息。

通过它的 .well-known 端点来访问服务器的配置信息,在浏览器的地址栏中,输入地址:http://localhost:5050/.well-known/openid-configuration,并回车,可以看到对应的响应信息。

五、模板

在上文中,我们通过手动搭建的方式,从一个空模板的搭建,到引用对应的Nuget包,安装修改配置,并搭配了官方提供的UI界面,初步形成了一个简易的IdentityServer4初始化项目框架,这种一步步的构建项目的方式。

官方也给我们提供了对应的快捷创建项目的模板,所以,如果你不想创建MVC项目,可以用官方提供的模板方式进行创建初始化项目。

5.1. 安装模板

dotnet new -i IdentityServer4.Templates

在命令的输出中,可以看到已经安装了多个关于 IdentityServer4 的模版

模板 简称 说明
IdentityServer4 with AdminUI is4admin 这为用户、身份、客户端和资源提供了一个基于web的管理界面.该社区版本旨在测试IdentityServer集成场景,并且仅限于本地主机:5000、SQLite、10个用户和2个客户端。社区版不适合生产应用。
IdentityServer4 with ASP.NET Core Identity is4aspid 添加使用ASP.NET标识进行用户管理的基本IdentityServer。如果您自动启动数据库,您将得到两个用户:Alice和bob--都带有密码Pass123$。检查SeedData.cs文件。
IdentityServer4 Empty is4empty 在没有UI的情况下创建一个最小的IdentityServer4项目。
IdentityServer4 with Entity Framework Stores is4ef 添加使用实体框架进行配置和状态管理的基本IdghtyServer。如果您启动数据库,您将获得一些基本的客户端和资源注册,请检查SeedData.cs文件。
IdentityServer4 with In-Memory Stores and Test Users is4inmem 添加具有UI、测试用户和示例客户端和资源的基本IdentityServer。显示内存中的代码和JSON配置。
IdentityServer4 Quickstart UI (UI assets only) is4ui 将快速启动UI添加到当前项目(例如,可以在is4empty的基础上添加)

5.2. 选择项目

这里面最为简单的项目模版就是 IdentityServer4 with In-Memory Stores and Test Users 了,它简称为 is4inmem ,我们下面就使用它来创建项目。

dotnet new 模板名 -n 项目名称

5.3. 启动应用

启动项目后,

可以看到项目的效果跟我们之前一步步搭建的效果是一样的,这说明我们已经创建了第一个可运行的 IdentityServer4 服务器了。

六、说明

6.1. HS256与RS256

JWT签名算法中,一般有两个选择,一个采用HS256,另外一个就是采用RS256。

签名实际上是一个加密的过程,生成一段标识(也是JWT的一部分)作为接收方验证信息是否被篡改的依据。

  1. HS256 使用密钥生成固定的签名,简单地说,HS256 必须与任何想要验证 JWT的 客户端或 API 共享密钥,因此必须注意确保密钥不被泄露。
  2. RS256 生成非对称签名,这意味着必须使用私钥来签签名 JWT,并且必须使用对应的公钥来验证签名。与对称算法不同,使用 RS256 可以保证服务端是 JWT 的签名者,因为服务端是唯一拥有私钥的一方。这样做将不再需要在许多应用程序之间共享私钥。

因此,在开发应用的时候启用JWT时候,使用RS256更加安全,你可以控制谁能使用什么类型的密钥。同时可以让服务端是唯一拥有私钥的一方,不需共享私钥。

6.2 关于证书

  生产环境(负载集群)一般需要使用固定的证书签名与验签,以确保重启服务端或负载的时候 Token 都能验签通过。(不使用临时证书)

6.2.1 创建证书

#生成私钥文件
openssl genrsa -out idsrv4.key 2048
#创建证书签名请求文件 CSR(Certificate Signing Request),用于提交给证书颁发机构(即 Certification Authority (CA))即对证书签名,申请一个数字证书。
openssl req -new -key idsrv4.key -out idsrv4.csr
#生成自签名证书(证书颁发机构(CA)签名后的证书,因为自己做测试那么证书的申请机构和颁发机构都是自己,crt 证书包含持有人的信息,持有人的公钥,以及签署者的签名等信息。当用户安装了证书之后,便意味着信任了这份证书,同时拥有了其中的公钥。)
openssl x509 -req -days 365 -in idsrv4.csr -signkey idsrv4.key -out idsrv4.crt
#自签名证书与私匙合并成一个文件
openssl pkcs12 -export -in idsrv4.crt -inkey idsrv4.key -out idsrv4.pfx 或
openssl req -newkey rsa:2048 -nodes -keyout idsrv4.key -x509 -days 365 -out idsrv4.cer
openssl pkcs12 -export -in idsrv4.cer -inkey idsrv4.key -out idsrv4.pfx

中途提示让你输入Export Password,这个password后面会用到。

6.2.2 项目配置

拷贝生成的证书,放到认证/授权服务器项目中。(VS中配置文件设置文件始终复制),最后把证书路径和密码配置到 IdentityServer 中,因为我们自签名的证书是 PKCS12 (个人数字证书标准,Public Key Cryptography Standards #12) 标准包含私钥与公钥)标准,包含了公钥和私钥。

A、在appsetting.json 配置文件中添加如下:此处需要配置password,即生成证书的时候输入的密码。

{
"Certificates": {
"CerPath": "certificate\\idsrv4.pfx",
"Password": "P@ssw0rd"
}
}

B、在starup.cs中ConfigureServices方法中配置如下即可。

var basePath = PlatformServices.Default.Application.ApplicationBasePath;
services.AddIdentityServer().AddSigningCredential(new X509Certificate2(
Path.Combine(basePath,Configuration["Certificates:CerPath"]),
Configuration["Certificates:Password"])
)

C、配置完后即可。我们启动IDS4项目即可生成加密的token。

6.2.3 提取补充

OpenSSL 提取 pfx 证书公钥与私钥

提取pfx证书公钥和私钥
从pfx证书中提取密钥信息,并转换为key格式(pfx使用pkcs12模式补足)
1. 提取密钥对(如果pfx证书已加密,会提示输入密码)
openssl pkcs12 -in idsrv4.pfx -nocerts -nodes -out idsrv4.key
2. 从密钥对提取公钥
openssl rsa -in idsrv4.key -pubout -out idsrv4_pub.key
3. 从密钥对提取私钥
openssl rsa -in idsrv4.key -out idsrv4_pri.key
4. 因为RSA算法使用的是 pkcs8 模式补足,需要对提取的私钥进一步处理得到最终私钥
openssl pkcs8 -topk8 -inform PEM -in idsrv4_pri.key -outform PEM -nocrypt

注意:

将得到的token在jwt.io 网站来认证一下,需要将 crt 公钥、key私钥复制到验证中,发现认证ok,则说明实现防篡改。

后缀为crt公钥需要带着 -----BEGIN CERTIFICATE----- 和 -----END CERTIFICATE----- 一起复制。

后缀为key私钥私钥需要带着 -----BEGIN RSA PRIVATE KEY----- 和 -----END RSA PRIVATE KEY----- 一起复制。

七、总结

  1. 在本篇中我们通过手动或者官方模板的方式简易的实现了我们的IdentityServer授权服务器搭建,并做了相应的配置和UI配置,实现了获取Token方式。
  2. 对于相应的配置我们需要注意的三个点就是,有哪些用户(users)可以通过哪些客户端(clents)来访问我们的哪些API保护资源 (API)。
  3. 在后续会对其中的授权模式,数据库持久化问题,以及如何应用在API资源服务器中和配置在客户端中,会进一步说明。
  4. 如果有不对的或不理解的地方,希望大家可以多多指正,提出问题,一起讨论,不断学习,共同进步。
  5. 项目地址

八、资料

IdentityServer4官方文档

IdentiytServer4模板

IdentityServer4界面

IdentityServer4系列 | 快速搭建简易项目的更多相关文章

  1. Spring Boot入门-快速搭建web项目

    Spring Boot 概述: Spring Boot makes it easy to create stand-alone, production-grade Spring based Appli ...

  2. 快速搭建Vue项目

    快速搭建Vue项目 第一次安装vue项目Vue推荐开发环境Node.js 6.2.0.npm 3.8.9.webpack 1.13.vue-cli 2.5.1.webstrom2016 安装环境: 安 ...

  3. 在线官网Spring Initializr 或 IntelliJ IDEA 快速搭建springboot项目

    Spring Boot是由Pivotal团队提供的全新框架,设计目的是用来简化新Spring应用的初始搭建以及开发过程.它主要推崇的是'消灭配置’,实现零配置. 那么,如何快速新建一个一个spring ...

  4. (05节)快速搭建SSM项目

    1.1  快速搭建Web项目 注意点:name:archetypeCatalog,value:internal 原因:Intellij IDEA根据maven archetype的本质,执行mvn a ...

  5. 小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_2-2.快速搭建SpringBoot项目,采用IDEA

    笔记 2.快速搭建SpringBoot项目,采用IDEA     简介:使用SpringBoot start在线生成项目基本框架并导入到IDEA中 参考资料:         IDEA使用文档    ...

  6. 小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_2-1.快速搭建SpringBoot项目,采用Eclipse

    笔记 1.快速搭建SpringBoot项目,采用Eclipse     简介:使用SpringBoot start在线生成项目基本框架并导入到eclipse中 1.站点地址:http://start. ...

  7. 使用IDEA快速搭建Springboot项目

    Spring Boot是由Pivotal团队提供的全新框架,设计目的是用来简化新Spring应用的初始搭建以及开发过程.它主要推崇的是'消灭配置’,实现零配置. 下面就介绍一下如何使用idea快速搭建 ...

  8. Spring-Boot快速搭建web项目详细总结

    最近在学习Spring Boot 相关的技术,刚接触就有种相见恨晚的感觉,因为用spring boot进行项目的搭建是在太方便了,我们往往只需要很简单的几步,便可完成一个spring MVC项目的搭建 ...

  9. 利用vue-cli3快速搭建vue项目详细过程

    一.介绍 Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统.有三个组件: CLI:@vue/cli 全局安装的 npm 包,提供了终端里的vue命令(如:vue create .vue ...

随机推荐

  1. 什么是 session 和 cookie

    cookie 大家应该都熟悉,比如说登录某些网站一段时间后,就要求你重新登录:再比如有的同学很喜欢玩爬虫技术,有时候网站就是可以拦截住你的爬虫,这些都和 cookie 有关.如果你明白了服务器后端对于 ...

  2. 浅析 AC 自动机

    目录 简述 AC 自动机是什么 AC 自动机有什么用 AC 自动机·初探 AC 自动机·原理分析 AC 自动机·代码实现 AC 自动机·更进一步 第一题 第二题 第三题 从 AC 自动机到 fail ...

  3. PASS模型-第一周个人报告

    PASS模型-第一周个人报告 博客班级 https://edu.cnblogs.com/campus/zjcsxy/SE2020 作业要求 https://edu.cnblogs.com/campus ...

  4. 分布式文档存储数据库之MongoDB索引管理

    前文我们聊到了MongoDB的简介.安装和对collection的CRUD操作,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/13941797.html:今天我 ...

  5. SVG--D3--血缘关系树

    最近的工作与可视化有关,有展示血缘关系树的需求 ,类似于这样: 碰巧搜到 D3(用于可视化的js库,作者吕之华),瞬间无法自拔,它的树状图功能基于SVG.js ,暴露的可操作入口也简洁恰当,能帮助你快 ...

  6. CDM 设置 主键自增

    一些朋友在用PD建概念模型时,觉得主键无法设置自增,还需要在生成PDM后,单独再设置一次,很麻烦. 自增主键一般都是整形,int ,long 如果我们在CDM建实体模型时,将自增主键设置为Serial ...

  7. Java学习之路(一)——JDK的下载与安装

    (一).JDK是Java开发工具包 下载网址:https://www.oracle.com/java/technologies/javase-downloads.html (二).安装 下载JDK以后 ...

  8. 谈谈volatile

    volatile的作用: volatile关键字的作用包括:保障可见性,保障有序性. 何为保障可见性,看下面的代码: package com.mashibing.thread.lock; public ...

  9. 【转】volatile和synchronized的区别

    volatile和synchronized的区别 volatile本质是在告诉jvm当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取: synchronized则是锁定当前变量,只有当前 ...

  10. HashMap 链表插入方式 → 头插为何改成尾插 ?

    开心一刻 一天,楼主在路上碰到了一个很久没见的朋友,找了个餐馆,坐下聊了起来 楼主:在哪上班了 ? 朋友:火葬场啊 楼主:在那上班,一个月多少钱啊 ? 朋友:两万多啊 楼主(不可思议):多少 ? 朋友 ...