驾一叶之扁舟 举匏樽以相属
寄蜉蝣于天地,渺沧海之一粟。哀吾生之须臾,羡长江之无穷。
挟飞仙以遨游,抱明月而长终。知不可乎骤得,托遗响于悲风。

从壹开始 [ Ids4 ] 之二║ 基础知识集合 & 项目搭建一

前言

哈喽大家又见面啦,感觉好久没更新了,这几天看了一本书《解忧杂货铺》,嗯挺好的,推荐一下😀。

 

不过还是要学习了,这些天简单的看了看 Id4 的资料,才发现原来关于 Id4 的系列文章真是数不胜数,而且还有很多的深度好文章, 说的灰常之详细,所以一度打消了我写这一系列的冲动和信心,不过还是有一部分的小伙伴还没有学习过,所以我决定我以后就把 IdentityServer4 的基础概念知识点,就少写些,重点写如何在项目中使用吧,本文的知识点,简单过一遍,脑子里有这个东西就行了,再以后的开发中,多动手就知道了,特别简单的,这里说明一下,在以前的Blog.Core 系列中,有关 JWT 的知识,我单拎出来一个小Demo,有不懂的可以下载看看(https://github.com/anjoy8/BlogArti/tree/master/Blog.Core_JWT)。

重要!!!

本文中的内容是Ids4 v3版本的,如果有问题,我建议看看文章下边的评论区,里边有v4版本的。

 

零、今天要完成红色的部分

 

 

 

一、常见术语

 

1、身份认证服务器(IdentityServer)

IdentityServer 是基于OpenID Connect协议标准的身份认证和授权程序,它实现了OpenID Connect 和 OAuth 2.0 协议。

同样的角色,不同的文档使用不同的术语。在有些文档中,它(IdentityServer)可能会被叫做安全令牌服务器(security token service)、身份提供者(identity provider)、授权服务器(authorization server)、 标识提供方((IP-STS,什么是IP-STS)等等。

但是它们都是一样的,都是向客户端发送安全令牌(security token),

IdentityServer有许多功能:

  • 保护你的资源
  • 使用本地帐户或通过外部身份提供程序对用户进行身份验证
  • 提供会话管理和单点登录
  • 管理和验证客户机
  • 向客户发出标识和访问令牌
  • 验证令牌

 

2、用户(User)

用户是使用已注册的客户端(指在id4中已经注册)访问资源的人。

 

3、客户端(Client)

客户端就是从identityserver请求令牌的软件(你可以理解为一个app即可),既可以通过身份认证令牌来验证识别用户身份,又可以通过授权令牌来访问服务端的资源。但是客户端首先必须在申请令牌前已经在identityserver服务中注册过。

实际客户端不仅可以是Web应用程序,app或桌面应用程序(你就理解为pc端的软件即可),SPA,服务器进程等。

 

4、资源(Resources)

资源就是你想用identityserver保护的东东,可以是用户的身份数据或者api资源。
每一个资源都有一个唯一的名称,客户端使用这个唯一的名称来确定想访问哪一个资源(在访问之前,实际identityserver服务端已经配置好了哪个客户端可以访问哪个资源,所以你不必理解为客户端只要指定名称他们就可以随便访问任何一个资源)。

用户的身份信息实际由一组claim组成,例如姓名或者邮件都会包含在身份信息中(将来通过identityserver校验后都会返回给被调用的客户端)。

API资源就是客户端想要调用的功能(通常以json或xml的格式返回给客户端,例如webapi,wcf,webservice),通常通过webapi来建立模型,但是不一定是webapi,我刚才已经强调可以使其他类型的格式,这个要看具体的使用场景了。

 

 

5、访问令牌(Access Token)

访问令牌允许访问API资源。 客户端请求访问令牌并将其转发到API。 访问令牌包含有关客户端和用户的信息(如果存在)。 API使用该信息来授权访问其数据。

访问令牌允许客户端访问某个 API 资源。客户端请求到访问令牌,然后使用这个令牌来访问 API资源。访问令牌包含了客户端和用户(如果有的话,这取决于业务是否需要,但通常不必要)的相关信息,API通过这些令牌信息来授予客户端的数据访问权限。

OAuth2提供了Access Token来解决授权第三方客户端访问受保护资源的问题;

 

 

 

6、身份令牌(Id Token)

上面提到过OIDC对OAuth2最主要的扩展就是提供了ID Token。ID Token是一个安全令牌,是一个授权服务器提供的包含用户信息(由一组Cliams构成以及其他辅助的Cliams)的JWT格式的数据结构。ID Token的主要构成部分如下(使用OAuth2流程的OIDC)。

  1. iss = Issuer Identifier:必须。提供认证信息者的唯一标识。一般是一个https的url(不包含querystring和fragment部分)。
  2. sub = Subject Identifier:必须。iss提供的EU的标识,在iss范围内唯一。它会被RP用来标识唯一的用户。最长为255个ASCII个字符。
  3. aud = Audience(s):必须。标识ID Token的受众。必须包含OAuth2的client_id。
  4. exp = Expiration time:必须。过期时间,超过此时间的ID Token会作废不再被验证通过。
  5. iat = Issued At Time:必须。JWT的构建的时间。
  6. auth_time = AuthenticationTime:EU完成认证的时间。如果RP发送AuthN请求的时候携带max_age的参数,则此Claim是必须的。
  7. nonce:RP发送请求的时候提供的随机字符串,用来减缓重放攻击,也可以来关联ID Token和RP本身的Session信息。
  8. acr = Authentication Context Class Reference:可选。表示一个认证上下文引用值,可以用来标识认证上下文类。
  9. amr = Authentication Methods References:可选。表示一组认证方法。
  10. azp = Authorized party:可选。结合aud使用。只有在被认证的一方和受众(aud)不一致时才使用此值,一般情况下很少使用。

ID Token通常情况下还会包含其他的Claims(毕竟上述claim中只有sub是和EU相关的,这在一般情况下是不够的,必须还需要EU的用户名,头像等其他的资料,OIDC提供了一组公共的cliams,请移步这里http://openid.net/specs/openid-connect-core-1_0.html#StandardClaims)。另外ID Token必须使用JWS进行签名和JWE加密,从而提供认证的完整性、不可否认性以及可选的保密性。

 

OIDC在这个基础上提供了ID Token来解决第三方客户端标识用户身份认证的问题。OIDC的核心在于在OAuth2的授权流程中,一并提供用户的身份认证信息(ID Token)给到第三方客户端,ID Token使用JWT格式来包装,得益于JWT(JSON Web Token)的自包含性,紧凑性以及防篡改机制,使得ID Token可以安全的传递给第三方客户端程序并且容易被验证。此外还提供了UserInfo的接口,用户获取用户的更完整的信息。

简而言之ID Token就是JWT格式的数据,包含一个人类用户的身份认证的信息,一个ID Token的例子如下:

 

 

 

7、刷新令牌(Refresh Token)

access token 是客户端访问资源服务器的令牌。拥有这个令牌代表着得到用户的授权。然而,这个授权应该是临时的,有一定有效期。这是因为,access token 在使用的过程中可能会泄露。给 access token 限定一个较短的有效期可以降低因 access token 泄露而带来的风险。

  然而引入了有效期之后,客户端使用起来就不那么方便了。每当 access token 过期,客户端就必须重新向用户索要授权。这样用户可能每隔几天,甚至每天都需要进行授权操作。这是一件非常影响用户体验的事情。希望有一种方法,可以避免这种情况。

  于是 Oauth2.0 引入了 refresh token 机制。refresh token 的作用是用来刷新 access token。鉴权服务器提供一个刷新接口,例如:

  http://xxx.xxx.com/refresh?refreshtoken=&client_id=

  传入 refresh token 和 client_id,鉴权服务器验证通过后,返回一个新的 access token。为了安全,Oauth2.0 引入了两个措施:

  1,Oauth2.0 要求,refresh token 一定是保存在客户端的服务器上的,而绝不能存放在狭义的客户端(例如移动 app、PC端软件) 上。调用 refresh 接口的时候,一定是从服务器到服务器的访问;

  2,Oauth2.0 引入了 client_secret 机制。即每一个 client_id 都对应一个 client_secret。这个 client_secret 会在客户端申请 client_id 时,随 client_id 一起分配给客户端。客户端必须把 client_secret 妥善保管在服务器上,决不能泄露。刷新 access token 时,需要验证这个 client_secret。

  于是,实际上的刷新接口应该是类似这样的:

  http://xxx.xxx.com/refresh?refreshtoken=&client_id=&client_secret=

  以上就是 refresh token 机制。refresh token 的有效期非常长,会在用户授权时,随 access token 一起重定向到回调 url,传递给客户端。

 

 

二、 OAuth 2.0 和 OpenID Connect

1、什么是OAuth2.0 ?

OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。就比如我用QQ登录博客园,那博客园(第三方应用)的昵称就可以是我的QQ(某网站)昵称,它获取到了我的QQ昵称,并存到了博客园的数据库,我以后就一直可以使用QQ来登录博客园,但是博客园却不知道我QQ的用户名和密码。

OAuth 允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据。每一个令牌授权一个特定的网站(例如,视频编辑网站)在特定的时段(例如,接下来的 2 小时内)内访问特定的资源(例如仅仅是某一相册中的视频)。这样,OAuth 让用户可以授权第三方网站访问他们存储在另外服务提供者的某些特定信息,而非所有内容。

OAuth 2.0 四种授权模式:

 

授权码模式(authorization code)

简化模式(implicit grant type) 

密码模式(resource owner password credentials)

客户端模式(Client Credentials Grant)

  

具体的概念和如何使用不细说,以后会分四篇文章详细说明,今天主要是基础知识和项目的搭建。

 

2、什么是 OpenID Connect ?

简单来说:

  • OpenID Connect是基于OAuth 2.0规范族的可互操作的身份验证协议。它使用简单的REST / JSON消息流来实现,和之前任何一种身份认证协议相比,开发者可以轻松集成。
  • OpenID Connect允许开发者验证跨网站和应用的用户,而无需拥有和管理密码文件。
  • OpenID Connect允许所有类型的客户,包括基于浏览器的JavaScript和本机移动应用程序,启动登录流动和接收可验证断言对登录用户的身份。

进一步来说:
  • OpenID Connect是OAuth 2.0协议之上的简单身份层,用 API 进行身份交互的框架,允许客户端根据授权服务器的认证结果最终确认用户的身份,以及获取基本的用户信息
  • 它支持包括Web、移动、JavaScript在内的所有客户端类型;
  • 它是可扩展的协议,允许你使用某些可选功能,如身份数据加密、OpenID提供商发现、会话管理;
OpenID Connect vs OpenID 2.0:OpenID Connect完成很多与OpenID 2.0相同的任务,是API-friendly,定义了可选的签名和加密的机制;OAuth 1.0和OpenID 2.0的集成需要扩展,而OpenID Connect协议本身就建立在OAuth 2.0之上。

为什么开发者要使用OpenID Connect?
因为它很简单,可靠,安全,并让他们摆脱困难和危险的存储和管理别人的密码。也有好处,它让用户的生活更容易在网站注册和注册从而减少遗弃。

 

3、JWT 和 OAuth2.0 的比较

要比较JWT和OAuth2,首先要明白一点就是,这两个根本没有可比性,是两个完全不同的东西。

  • JWT是一种认证协议
    JWT提供了一种用于发布接入令牌(Access Token),并对发布的签名接入令牌进行验证的方法。 令牌(Token)本身包含了一系列声明,应用程序可以根据这些声明限制用户对资源的访问。

  • OAuth2是一种授权框架
    另一方面,OAuth2是一种授权框架,提供了一套详细的授权机制(指导)。用户或应用可以通过公开的或私有的设置,授权第三方应用访问特定资源

既然 JWT和OAuth2.0 没有可比性,为什么还要把这两个放在一起说呢?实际中确实会有很多人拿 JWT和OAuth2.0 作比较。很多情况下,在讨论OAuth2的实现时,会把JSON Web Token作为一种认证机制使用。这也是为什么他们会经常一起出现。

 

4、OpenID 是怎么认证用户的?

一个网站如果想要接入 OpenID 认证是非常简单的,不需要创建应用,不需要 App Key ,不需要 Secret ,只需要将用户导向 OpenID Provider 的 Entry 并带上 Callback ,用户只要同意提供信息,你就可以拿到这个用户的“唯一标识”。

请注意这里我使用了“唯一标识”这种说法,因为对于网站来说,OpenID Provider 提供的既不是用户的 UID ,也不是用户的 E-Mail ,比如 Google 在默认情况下提供的就是一个几十位长的字符串,这个字符串是随机生成的,第三方网站无法从中获得用户的任何私人信息。这么说可能很抽象,举个例子:

比如我用 Google 的 OpenID 服务登录 xxx.com , xxx.com 先把我导向 Google 的授权页面,我使用 Google 帐号 test@gmail.com 登录并同意后,页面跳回 xxx.com , xxx.com 拿到了我的“唯一标识”,这个唯一标识可能是 cdxxxxxxxaaf6b73bcb04a1 ,xxx.com 从这个字符串里无法获得任何 test@gmail.com 的个人信息(甚至连邮箱地址也不知道), xxx.com 只知道以后只要使用谷歌登录并返回 cdxxxxxxxaaf6b73bcb04a1 这个标识符,那就是我在登录。

显而易见,OpenID 是专为登录认证而生,它使用简单,门槛很低,但是如果你想在认证过程中获得用户的其他信息(比如 E-Mail )就得多做一步了。

你这个时候可能就会问了,那有哪些网站使用的是 OpenID 登录的呢,我简单看了看,好像都是基于 OAuth 开发的,而且也看到了一个博问,是这么说的:

具体的咱们就不分析了,现在基本都是使用的 OAuth2.0 ,不过现在使用  Id4 是结合了 OAuth2.0 和 OpenID的。

 

5、OAuth 又是怎么认证用户的?

 

与 OpenID 相比,网站想接入 OAuth 要稍微麻烦点,网站需要先创建应用,拿到 Key 和 Secret ,才能接入 Provider 。

OAuth 的授权过程并不是身份认证的过程,这一点需要特别清楚,网站走完 OAuth 流程并拿到用户的授权 token 后还需要通过 token 调用相应的用户信息接口才能获得“唯一标识”,举个例子:

我想通过新浪微博登录 xxx.com ,xxx.com 要先把我 redirect 到新浪微博的授权页面,我通过微博帐号登录并授权后,页面跳回 xxx.com ,xxx.com 拿到我的访问 token 后还要再调用一个接口来获得我的新浪会员 UID ,这个 UID 就是新浪用户的“唯一标识”了。

可以看出,OAuth 相对于 OpenID 最大的区别就是,网站实际上是拿到了你的帐户访问权限继而确认你的身份,这是一个安全隐患,因为网站在拿到你的“唯一标识”的同时还拿到了一把你的账户的 “临时钥匙”。至于网站会不会拿这把钥匙“干坏事”,这个只有站长心里清楚。同时 OAuth 还比 OpenID 多了几个额外的请求步骤,登录所费时间一定是长于 OpenID 的。

 

6、OAuth和OpenID的区别

OAuth关注的是authorization;而OpenID侧重的是authentication。从表面上看,这两个英文单词很容易混淆,但实际上,它们的含义有本质的区别:

  • authorization: n. 授权,认可;批准,委任
  • authentication: n. 证明;鉴定;证实

OAuth关注的是授权,即:“用户能做什么”;而OpenID关注的是证明,即:“用户是谁”。

 

OpenID是关于证明、证实身份(Authentication)的,好比火车站进站的时候拿出身份证和车票来看,比对是否同一个人。这是在回答「我是谁?这就是我」,是为了证实「这不是一个匿名的不可查的信息源头」,因为匿名对象和信息对网络服务商来说不好统计管理,也不利于产生价值。

OAuth 是关于授权、许可(Authorization)的,好比坐飞机过安检的时候除了看身份证,还要求掏出兜里的东西,拿出包里的东西、手机等随身物品以便检查,这时就需要得到被检查人的许可才行,被检查人有权利扭头就走,但要想登机,必须给予许可、掏出物品。这是在回答「我同意让你对我进一步做些什么」,是为了在被授予权限的前提下,更多的获取除了账号密码以外的个人信息,例如:联系人通讯录,邮箱号,电话号,地址,照片,聊天记录,网络发言、活动记录,GPS 信息等等,来满足用户对服务的功能需要,或者「其他需要」。

 

//这里有个网友的说明,我感觉挺好的

 如今越来越多的网站,以及一些应用程序都开始使用第三方社交平台账户登录,那这里就会涉及到安全性的问题,隐私的问题,你不能随意来获取我的资料,当然你来使用我的资料,你要经过用户的同意,那这个用户是不是我平台上,还是要来向我求证,那在这个过程中,实际上就出现了两个过程,我们还是直接使用上次的例子来说明,比较直观,CSDN使用QQ登录,进入csdn的登录页,点击使用QQ登录:

   


       在进入到QQ登录界面后,最开始是要请求认证,用户输入QQ号和密码,点击登录,腾讯互联会先进行验证该用户是否为我的用户,如果是我的用户,那么我会通知你(CSDN),他是我的用户,你可以使用该账户登录你的系统,这个过程就是认证(Authentication),认证就是证明你是谁,你是否是真实存在的,就好像,快递员来给你送快递,让你出示你的身份证,他确定你是本人后,把快递给你,这就是OpenID。

      而在QQ授权登录下方,有两给CheckBox复选框,可以允许CSDN获得您的昵称、头像、性别,这是在认证之后的事了,在腾讯互联你是我平台的用户后,你可以自己选择CSDN是否有权去获取你的相关信息,当你勾选后,腾讯互联就把你的这些基本信息给了CSDN,这个过程就是授权(Authorization),授权就是确定了你是谁后,又把属于你的东西给了别人,犹如你向快递员出示了身份证,然后你又把你房门的密码给了他,并告诉他说,我把房门密码给你,你帮我放到我客厅里吧。

  

 

7、OAuth 、OpenID 和 OpenID Connect 的关系

简要而言,OIDC是一种安全机制,用于应用连接到身份认证服务器(Identity Service)获取用户信息,并将这些信息以安全可靠的方法返回给应用。

在最初,因为OpenID1/2经常和OAuth协议(一种授权协议)一起提及,所以二者经常被搞混。

  • OpenIDAuthentication,即认证,对用户的身份进行认证,判断其身份是否有效,也就是让网站知道“你是你所声称的那个用户”;
  • OAuthAuthorization,即授权,在已知用户身份合法的情况下,经用户授权来允许某些操作,也就是让网站知道“你能被允许做那些事情”。
    由此可知,授权要在认证之后进行,只有确定用户身份只有才能授权。

(身份验证)+ OAuth 2.0 = OpenID Connect

OpenID Connect是“认证”和“授权”的结合,因为其基于OAuth协议,所以OpenID-Connect协议中也包含了client_idclient_secret还有redirect_uri等字段标识。这些信息被保存在“身份认证服务器”,以确保特定的客户端收到的信息只来自于合法的应用平台。这样做是目的是为了防止client_id泄露而造成的恶意网站发起的OIDC流程。

举个例子。某个用户使用Facebook应用“What online quiz best describes you?” ,该应用可以通过Facebook账号登录,则你可以在应用中发起请求到“身份认证服务器”(也就是Facebook的服务器)请求登录。这时你会看到如下界面,询问是否授权。

 

 在 OAuth 中,这些授权被称为scope。OpenID-Connect也有自己特殊的scope--openid ,它必须在第一次请求“身份鉴别服务器”(Identity Provider,简称IDP)时发送过去。

 

 

三、创建基于EFCore的Idp项目 

 

你可以参考官方文档:Docs » Welcome to IdentityServer4

 

1、建立空的NetCore MVC 项目

这个过程很简单,因为你能看这个系列,证明你的 NetCore 功底已经很高了,至少中等,如果不会,请时光机回到我的第一个前后端分离系列。

1、创建一个新的ASP.NET Core项目;//可以使用命令行创建

2、选择“空白”选项;//这里创建空的应用程序是为了后面方便引入UI界面

3、设置项目使用 kestrel 服务器,删除IIS;

4、配置端口号;//我这里是5002,可自定义设置

 

 

1.1、使用官方提供的模板

如果你不想创建MVC项目,可以用官方提供的模板:

dotnet new -i IdentityServer4.Templates

dotnet new is4empty -n IdentityServer

 

 

 (这是我视频教程中的导图)

 

2、安装并配置IdentityServer4

1、使用 nuget 添加 IdentityServer4 包;//当然你也可以使用命令: Install-Package IdentityServer4

2、配置认证服务中间件管道;//app.UseIdentityServer();

3、配置 IdentityServer 相关服务;

 

 

这里不仅要把 IdentityServer 注册到容器中, 还要至少对其配置四点内容:

1、这个 Authorization Server 保护了哪些 API (资源);

2、哪些客户端 Client(应用) 可以使用这个 Authorization Server;

3、指定可以使用 Authorization Server 授权的 Users(用户);

4、指定作用域定义系统中的 IdentityResources 资源;//这个在以后说到 OpenId的时候再说,这里伏笔

首先在项目根目录下,建立文件 InMemoryConfig.cs:

    public static class InMemoryConfig
    {
        // 这个 Authorization Server 保护了哪些 API (资源)
        public static IEnumerable<ApiResource> GetApiResources()
        {
            return new[]
            {
                    new ApiResource("blog.core.api", "Blog.Core API")
                };
        }
        // 哪些客户端 Client(应用) 可以使用这个 Authorization Server
        public static IEnumerable<Client> GetClients()
        {
            return new[]
            {
                    new Client
                    {
                        ClientId = "blogvuejs",//定义客户端 Id
                        ClientSecrets = new [] { new Secret("secret".Sha256()) },//Client用来获取token
                        AllowedGrantTypes = GrantTypes.ResourceOwnerPasswordAndClientCredentials,//这里使用的是通过用户名密码和ClientCredentials来换取token的方式. ClientCredentials允许Client只使用ClientSecrets来获取token. 这比较适合那种没有用户参与的api动作
                        AllowedScopes = new [] { "blog.core.api" }// 允许访问的 API 资源
                    }
                };
        }
        // 指定可以使用 Authorization Server 授权的 Users(用户)
        public static IEnumerable<TestUser> Users()
        {
            return new[]
            {
                    new TestUser
                    {
                        SubjectId = "1",
                        Username = "laozhang",
                        Password = "laozhang"
                    }
            };
        }
    }

 

PS:现在Ids4的版本已经是4.x系列了,会有部分差异,具体更新,可以看我的另一篇文章

https://mp.weixin.qq.com/s/C1JTz15pBkx4uUa_6qN_eA

 

GetApiResources:这里指定了name和display name, 以后api使用authorization server的时候, 这个name一定要一致, 否则就不好用的。

GetClients: Client的属性太多了,基本的上边已经注释了

Users: 这里的内存用户的类型是TestUser, 只适合学习和测试使用, 实际生产环境中还是需要使用数据库来存储用户信息的, 例如接下来会使用asp.net core identity. TestUser的SubjectId是唯一标识.

 

 

然后回到 Startup 的 ConfigureServices 方法种:

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

    public class Startup
    {

        public IConfiguration Configuration { get; }
        public IHostingEnvironment Environment { get; }

        public Startup(IConfiguration configuration, IHostingEnvironment environment)
        {
            Configuration = configuration;
            Environment = environment;
        }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();

            var builder = services.AddIdentityServer(options =>
            {
                options.Events.RaiseErrorEvents = true;
                options.Events.RaiseInformationEvents = true;
                options.Events.RaiseFailureEvents = true;
                options.Events.RaiseSuccessEvents = true;
            })
            // in-memory, code config
            .AddTestUsers(InMemoryConfig.Users().ToList())
            .AddInMemoryApiResources(InMemoryConfig.GetApiResources())
            .AddInMemoryClients(InMemoryConfig.GetClients());


            builder.AddDeveloperSigningCredential();

            if (Environment.IsDevelopment())
            {
                builder.AddDeveloperSigningCredential();
            }
            else
            {
                throw new Exception("need to configure key material");
            }

            services.AddAuthentication();//配置认证服务

        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseIdentityServer();//启动 IdentityServer
            app.UseMvcWithDefaultRoute();//启动 MVC,这是netcore 2.2 的内容,3.0自行做响应的修改。
        }
    }

 


 


 

 

 

然后运行一下,在 Postman 中,尝试通过上边的用户名密码来获取 Token :

 

 

 

 

 

是不是很熟悉,如果你用过 NetCore 的授权验证的话,这些肯定都能看懂。

这里你一定很好奇,我是怎么知道要使用这个地址 localhost:5002/connect/token 来获取Token的? ,一共还有多少个接口地址呢,要是有一个界面就好了。别着急往下看。IdentityServer4 官方已经考虑到了。

 

3、关于QuickStart UI

 官方为我们提供了一个快速启动的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'))

 

 

这样我们的项目界面已经成功的获取到了,除此之外,记得要配置中间件来使用静态文件:

app.UseStaticFiles();

 

4、运行展示 

配置好后,F5运行,就可以看到了欢迎界面,点击 discovery document,可以看到了我们上边说到的 token 获取的接口地址 localhost:5002/connect/token:

 (可能这个 Json 格式和你的不一样,因为我安装了chrome 的扩展插件了——JSONView)

 

5、配置 EFCore 连接到数据库

因为篇幅的问题,这个下次再详细说明,不过我的 GitHub 上已经写好了,有需要的可以看看。

 

6、关于证书问题

这里信息暂时没有用处,只是先作为一个备注记录,待以后补充完善:

参考地址:https://www.cnblogs.com/guolianyu/p/9872661.html

 

1、HS256与RS256的区别

HS256 使用密钥生成对称的签名,RS256 使用成非对称进行签名。简单地说,HS256 必须与任何想要验证 JWT的 客户端或 API 共享秘密。

RS256 生成非对称签名,这意味着必须使用私钥来签签名 JWT,并且必须使用对应的公钥来验证签名。与对称算法不同,使用 RS256 可以保证服务端是 JWT 的签名者,因为服务端是唯一拥有私钥的一方。这样做将不再需要在许多应用程序之间共享私钥

 

2、创建自签名证书(操作步骤)

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

那么证书如何生成请看下面分解步骤:

  第一种:使用OpenSSL生成证书,注:RSA加密证书长度要2048以上,否则服务运行会抛异常

复制代码
#Linux系统生成证书:(推荐使用)
sudo yum install openssl (CentOS)
#生成私钥文件 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 (包含公钥)
#自签名证书与私匙合并成一个文件(注:.pfx中可以加密码保护,所以相对安全些) openssl pkcs12 -export -in idsrv4.crt -inkey idsrv4.key -out idsrv4.pfx (注:在生成的过程中会让我们输入Export Password)
复制代码

 

 证书截图如下:

 

  第二种:

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

 

生成如下:

 

3、证书生成之后就可进入VS2017中配置

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

 A、在appsetting.json 配置文件中添加如下:此处需要配置password,自定义即可。

 

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

 

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

 

 

四、结语 

今天咱们主要通过一个小栗子,把我们的IdentityServer授权服务器搭建好了,并且做了相应配置,也获取到了 Token ,是不是很简单?感觉 Id4 也没有我们想象的那么难是吧,关键就是上边的Config.cs 中的三个配置,总结来说:

有哪些用户可以通过哪些客户端来访问我们的哪些API保护资源

这要我们这些配置好了,自然我们也就可以使用 Id4 了,当然这个仅仅是获取到了 Token,那如何连数据库,如何应用在 API 资源服务器,又如何在客户端配置呢,咱们下次再见咯。

五、Github

 

https://github.com/anjoy8/Blog.IdentityServer

 

-- END ---

posted @ 2019-03-28 10:34  老张的哲学  阅读(18827)  评论(24编辑  收藏  举报
作者:老张的哲学
好好学习,天天向上
返回顶部小火箭
好友榜:
如果愿意,把你的博客地址放这里
jianshu.com/u/老张
SqlSugar codeisbug.com