聊聊统一身份认证服务

无人久伴 提交于 2020-01-20 19:46:57

导读

当企业的应用系统逐渐增多后,每个系统单独管理各自的用户数据容易形成信息孤岛,分散的用户管理模式阻碍了企业应用向平台化演进。当企业的业务发展到一定规模,构建统一的标准化账户管理体系将是必不可少的,因为它是企业云平台的重要基础设施,能够为平台带来统一的帐号管理、身份认证、用户授权等基础能力,为企业带来诸如跨系统单点登录、第三方授权登录等基础能力,为构建开放平台和业务生态提供了必要条件。

背景

公司原有的各个业务系统都是通过域账户来打通的,随着公司平台化、开放战略的推进,公司对外提供的服务必须具备对外集成与被集成的能力,在这种需求下,单纯的内部账户打通已显然不能满足需求,提供统一的账户管理、身份认证与授权势在必行。
以我们的DevOps平台研发协同平台为例,平台要面向ISV合作伙伴开放, 首先面临的就是账户问题,不单单是研发协同平台自身要向ISV合作提供服务,围绕研发协同平台的其他服务(例如Jira, Confluence, Jenkins, Sonar)也要面向ISV合作伙伴提供服务,这就要求面向ISV合作伙伴必须提供统一的账户体系。

需求

统一身份管理
统一身份管理是整个平台帐号和权限管控的基础,平台下所有系统的账户管理、身份认证、资源授权等行为都经由系统统一处理,提供帐号密码管理、基本资料管理、资源管理、授权管理、客户端管理等功能。统一身份管理基于统一身份治理的概念,可划分为账户体系、基础信息、资源授权三大模块。
其中账户体系将账户分为组织实体帐号和个人实体账户两大类,个人实体从属于组织实体,也可以不从属任何组织实体,且个人实体可同时从属于多个组织实体;基础信息模块用于描述组织实体和个人实体的基本信息,如组织实体名称、地址、法人,个人实体姓名、电话号码、性别等基础信息;资源授权模块将需要对外提供服务的业务服务资源进行统一管理和授权。

组织实体
在统一认证身份服务中,组织机构应当是一种实体,与之对应的另一种实体是个人实体(业务上是实体概念,和账户是有区别的)。因此要设计一种用于组织实体登入系统的方法,这里有两种可选方案:一是增加组织实体账户,组织实体自身拥有账户,可直接进行认证登录;二是将从属于组织实体的个人账户作为组织实体的登入凭证。无论何种方法,在认证和授权时,都由统一身份认证服务提供统一标准的账户凭证,因此,组织实体的认证授权与个人实体的认证授权并无二致

单点登录(SSO)
企业平台涉及众多子系统,为简化各子系统的用户管理,提升用户体验,因此实现 SSO 是统一身份认证的重要目标:一次登录,全部访问。对于企业内部应用来说,SSO 是必须的选项,例如企业 OA、HR、CRM 等内部系统;对于外部应用来说,SSO 是可选项,具体哪个应用应当加入 SSO 系统,由该业务系统决定。无论何种应用服务是否采用 SSO,统一身份认证服务在技术上应当具备 SSO 的能力。

授权登录
随着平台业务的逐渐增长,依托于平台的,和平台依托的厂商和客户等资源将极大的丰富平台,因此必须构筑开放的生态系统,以支撑业务的进一步发展。必须开放平台级的授权登录功能,以允许第三方应用接入。

资源授权
企业业务服务除了要集成第三方服务来提升服务能力,也需要对外提供服务,提供被集成的能力,这样才能和第三方一起构建生态合作伙伴关系,实现共赢。因此,统一身份认证服务除了要提供认证,还需要提供服务资源授权的能力,以授权第三方集成企业提供的业务服务,将企业的业务服务开放给第三方,实现共同发展。

技术方案

IdentityServer4是基于ASP.NET Core的OpenID Connect和OAuth 2.0框架。它提供了以下丰富的功能:
身份验证即服务
适用于所有应用程序(Web,本机,移动设备,服务)的集中登录逻辑和工作流程。IdentityServer是OpenID Connect 的官方认证实现。
单点登录/注销
在多种应用程序类型上单点登录(和退出)。
API访问控制
为各种类型的客户端发出API访问令牌,例如服务器到服务器,Web应用程序,SPA和本机/移动应用程序。
联合网关
支持Azure Active Directory,Google,Facebook等外部身份提供商。这可以保护您的应用程序免受如何连接到这些外部提供商的详细信息的影响。
可定制
最重要的部分 - IdentityServer的许多方面都可以根据您的需求进行定制。由于IdentityServer是一个框架而不是盒装产品或SaaS,因此您可以编写代码以使系统适应您的方案。
成熟的开源
IdentityServer使用允许的Apache 2许可证,允许在其上构建商业产品。它也是.NET Foundation的一部分,它提供治理和法律支持。

OAuth2.0 && OpenId Connect

IdentityServer4是基于ASP.NET Core的OpenID Connect和OAuth 2.0框架,我们先来了解OpenId Connect和OAuth 2.0的基本概念

OpenId
OpenID 是一个以用户为中心的数字身份识别框架,它具有开放、分散性。OpenID 的创建基于这样一个概念:我们可以通过 URI (又叫 URL 或网站地址)来认证一个网站的唯一身份,同理,我们也可以通过这种方式来作为用户的身份认证。
简而言之:OpenId用于身份认证(Authentication)
OAuth 2.0
OAuth(开放授权)是一个开放标准,目前的版本是2.0。允许用户授权第三方移动应用访问他们存储在其他服务商上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。
OAuth允许用户提供一个令牌而不是用户名和密码来访问他们存放在特定服务商上的数据。每一个令牌授权一个特定的网站内访问特定的资源(例如仅仅是某一相册中的视频)。这样,OAuth可以允许用户授权第三方网站访问他们存储在另外服务提供者的某些特定信息,而非所有内容。
OAuth是OpenID的一个补充,但是完全不同的服务。
简而言之:OAuth2.0 用于授权(Authorization)
OpenId Connect
OpenID Connect 1.0 是基于OAuth 2.0协议之上的简单身份层,它允许客户端根据授权服务器的认证结果最终确认终端用户的身份,以及获取基本的用户信息;它支持包括Web、移动、JavaScript在内的所有客户端类型去请求和接收终端用户信息和身份认证会话信息;它是可扩展的协议,允许你使用某些可选功能,如身份数据加密、OpenID提供商发现、会话管理等。
简而言之:OpenId Connect = OIDC = Authentication + Authorization + OAuth2.0

术语


了解完OpenId Connect和OAuth2.0的基本概念,我们再来梳理下涉及到的相关术语:

Identity Server
认证授权服务器,是OpenID Connect提供程序, 它实现了OpenID Connect和OAuth 2.0协议。主要包括以下功能:

  • 保护资源
  • 使用本地帐户存储或外部身份提供程序对用户进行身份验证
  • 提供会话管理和单点登录
  • 管理和验证客户端
  • 向客户发放身份和访问令牌
  • 验证令牌

用户(Users
用户是使用注册客户端访问资源的人

客户端(Client)
客户端是从IdentityServer请求令牌的应用 - 用于验证用户(请求身份令牌)或访问资源(请求访问令牌)。客户端必须首先向IdentityServer注册,然后才能请求令牌。常见的客户端包括Web应用程序,本机移动或桌面应用程序,SPA,服务器进程等。

资源(Resources)
使用IdentityServer保护的资源 - 用户的身份数据或服务资源(API)。每个资源都有一个唯一的名称 - 客户端使用此名称来指定他们希望访问哪些资源。身份数据 - 关于用户的身份信息(也称为声明),例如姓名或电子邮件地址等。服务资源(API) - 表示客户端要调用的服务 - 通常为Web API,但不一定。

令牌(Token)
令牌有身份令牌(Identity Token)和访问令牌(Access Token)。身份令牌表示身份验证的结果。它至少包含用户标识以及有关用户如何以及何时进行身份验证的信息,还可以包含其他身份数据。访问令牌允许访问API资源,客户端请求访问令牌并将其转发给API。访问令牌包含有关客户端和用户(如果存在)的信息,API使用该信息来授权访问其资源。

JWT认证

HTTP身份验证流程
HTTP提供了一套标准的身份验证框架:服务器可以用来针对客户端的请求发送质询(challenge),客户端根据质询提供身份验证凭证。质询与应答的工作流程如下:服务器端向客户端返回401(Unauthorized,未授权)状态码,并在WWW-Authenticate头中添加如何进行验证的信息,其中至少包含有一种质询方式。然后客户端可以在请求中添加Authorization头进行验证,其Value为身份验证的凭证信息。

Bearer认证(也叫做令牌认证)是一种HTTP认证方案,其中包含的安全令牌的叫做Bearer Token。因此Bearer认证的核心是Token。那如何确保Token的安全是重中之重。一种方式是使用Https,另一种方式就是对Token进行加密签名。而JWT就是一种比较流行的Token编码方式。

JWT(Json Web Token)
Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准。该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。
JWT有三部分组成:

<header>.<payload>.<signature>

Header - 由alg和typ组成,alg是algorithm的缩写,typ是type的缩写,指定token的类型。该部分使用Base64Url编码。

Payload - 主要用来存储信息,包含各种声明,同样该部分也由BaseURL编码。

Signature - 签名,使用服务器端的密钥进行签名。以确保Token未被篡改。

HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

授权模式

IdentityServer4提供了以下几种常见的授权模式:Client Credentials(客户端凭证模式), Resource Owner Password Credentials(密码模式), Implicit(简化模式),Authorization Code, Device Flow(设备模式)

Client Credentials (客户端凭证模式)

POST https://api.oauth2server.com/token grant_type=client_credentials& client_id=CLIENT_ID& client_secret=CLIENT_SECRET

客户端凭证模式是最简单的授权模式,因为授权的流程仅发生在Client与Identity Server之间。该模式的适用场景为服务器与服务器之间的通信。比如对于一个电子商务网站,将订单和物流系统分拆为两个服务分别部署。订单系统需要访问物流系统进行物流信息的跟踪,物流系统需要访问订单系统的快递单号信息进行物流信息的定时刷新。而这两个系统之间服务的授权就可以通过这种模式来实现。

Resource Owner Password Credentials (密码模式)

POST https://api.oauth2server.com/token grant_type=password& username=USERNAME& password=PASSWORD& client_id=CLIENT_ID

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

Implicit (简化模式)


Implicit Flow 又称为简化流程,因为没有任何后台服务参与使用 Authorization Grant 换取 Access Token 的流程,整个过程由 Browser 直接与 Authorization Server 通信。

Authorization Code


授权码模式是一种混合模式,是目前功能最完整、流程最严密的授权模式。它主要分为两大步骤:认证和授权。简称为 Code Flow,也是 OAuth 推崇的方案,该 Flow 同时采用了 Front Channel 和 Back Channel。它常见于 Web App 的场景。Client 应用程序通过 Front Channel 向 Authorization Server 申请 Authorization Code,再通过 Back Channel 用 Authorization Code 换取 Access Token。它假定 Resource Owner 和 Client 应用程序运行在不同的设备上,Access Token 始终不会传输到「用户代理应用程序」

Device Flow

用于类似 TV 等硬件设备,或仅仅运行一个 Cli 的程序,直接与 Authorization Server 通信取得一个 code,再用 code 换取 Access Token 的流程。

身份认证服务实践

在ASP.NET Core Wen API应用程序中配置和启用Identity server中间件

  • services.AddIdentityServer() - 配置identity server中间件
  • AddInMemoryIdentityResources - 配置身份资源
  • AddInMemoryApiResources - 配置API资源
  • AddInMemoryClients - 配置客户端
  • AddTestUsers - 配置用户

SonarQube集成身份认证服务授权登录

  1. 使用管理员身份登录SonarQube, 进入配置->通用设置->权限 设置OpenId Connect

  2. 设置完成,注销账户,在登录页面选择通过OpenId Connect登录, 即可使用身份认证服务授权登录SonarQube系统

写在最后

在互联网这个开放体系中,任务企业都可以集成第三方的服务来提升自己的服务能力,同时也可以将自己的服务能力开放给第三方提供被集成的能力,从而构建一个开放、共赢的生态体系。要开放、也要链接,而这绕不开的一个点就是认证授权问题。统一身份认证服务应运而生,各企业不再拘泥于内部的身份统一,在企业服务与企业服务之间建立安全可靠的链接,能够加强信息的流通、服务能力的提升,促进企业生态的发展。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!