1. 基本概念科普,以QA形式介绍一下https认证
1.1. 什么是HTTP(s)认证?
就是一种基于http协议(基于get、post请求)传输账号密码或其他参数,实现客户端和外部认证服务器之间认证和信息传输的一种认证方式,最后s的含义就是是否tls加密,根据api接口使用的是http还是https来决定
1.2. 零信任在什么场景可以使用HTTP(s)认证?
1、暴露面全收缩场景,所有业务及认证系统收收缩到零信任内,但是还想使用4A平台做统一身份认证;
2、SDK集成场景,https接口自由度高,开发简单,可传输自定义参数,可实现账号密码或者短信等认证方式
1.3. 和ldap、radius等类型认证方式有什么相同和不同?
相同点就是ldap、radius、http(s)这三种方式都可以基于零信任的认证页面来实现登录,不同的是,ldap和radius等都是固定的标准协议,只能传输固定的字段(账号+密码),而http认证自由度极高,其基于http接口,可以通过自定义请求体传输任意字段信息,典型场景就是sdk集成时,app需要和后端服务器交互自定义的字段信息,就可以通过https认证实现,本文也会基于实际案例做相关讲解
1.4. 和oauth、cas等票据类型认证方式有什么区别?
这两种都是基于标准的oauth、cas协议的认证,可以用于实现单点登录,但是http(s)认证本身不具备单点登录能力,因为不会产生认证票据;
oauth和cas在落地效果上,一般都是由“统一身份认证平台”来提供认证的web网页,不能直接在零信任认证页面输入账号密码认证,而http(s)认证方式可以直接使用零信任提供的认证页面输入账号密码,实现完整的暴露面收缩
1.5. 使用了http(s)认证方式之后还想做业务系统的票据单点登录怎么办?
使用cookie透传,本文后边会介绍;或者使用反向oauth解决,本文不做介绍,建议单独查询相关材料
2. 选择认证方案的三个关键点:
一是有没有用户目录服务器,二是用户接入方式,三是有没有统一身份认证服务器
2.1. 是否有用户目录服务器
用于判断是否具备自动同步账号信息的能力
如果有的话需要确认是什么目录服务器,确认零信任是否支持对接,如果没有用户目录服务器或者用户目录不支持对接,需要协商通过哪种方式解决(手动创建/表格导入/API/未导入用户允许登录)
2.2. 用户接入场景有哪些
用于筛选支持的认证方式
2.2.1. WEB、PC客户端、移动客户端接入场景
这些场景支持零信任本身在界面上提供的所有认证方式(PS:WEB接入不能使用基于客户端的认证能力比如SPA)
2.2.2. SDK集成接入场景
支持用户名/密码认证、短信主认证二次认证、ldap、radius、https(在此基础可实现令牌、cas账号密码、企业微信验证码、钉钉验证码、短信等)
2.3. 是否有统一身份认证平台?
用于评估用户登录的方式,需要确认内容如下:
2.3.1. 平台支持哪些认证方式和零信任对接?
Oauth/cas/ldap/radius/短信/http(s)/令牌等方式,如果不支持则无法和零信任对接,或者需要单独开发后再对接
2.3.2. 是否有业务系统单点登录需求?
如果有单点需求,则需要考虑使用票据认证(oauth/cas),或者使用https中的cookie代理下发
2.3.3. 认证页面使用4A的还是零信任的?
a. 如果使用4A平台做认证页,则可基于oauth/cas认证实现零信任和业务系统的单点。但是存在安全隐患,因为要把4A平台的认证页面暴露在公网
b. 如果使用零信任的认证页面,则可以解决暴露4A平台接口的问题,但是只能使用非票据类认证(本地用户/ldap/短信/radius/https/企业微信/钉钉/飞书扫码等),然后结合反向oauth解决单点登录问题,因为零信任页面提供的认证方式无法生成票据和业务系统共享认证,只能通过反向oauth触发生成业务系统可识别的票据
3. 认证方式对比
结合以上介绍已知http(s)认证适用的场景为全暴露面收缩场景,但是此场景下仍然有很多认证方式,接下来就介绍关于这些认证方式的优缺点,具体说明什么场景需要使用https(s)
a. 非https方式(本地/ldap/短信/radius/企业微信/钉钉/飞书等):这些方式的认证特点“标准”,优点是标准的接口可以直接对接使用,都是基于零信任的认证页面就可以直接用。缺点就是这些方式的自由度较低,无法实现个性化需求,如前后端传输自定义参数等需求无法满足
b. https方式:可以实现和本地/ldap/radius一样的认证效果,可以直接在零信任的认证页面输入账号密码登录,在此基础上又具有较高自由度,可通过轻量开发实现前后端互相传参,传输特定字段等需求。基于自由开发的特性,更适合用户sdk集成场景,因为sdk集成场景往往存在客户端-认证服务器之间传输自定义参数的需求,如app自身会发送如客户端id等字段到服务器进行认证,服务器也会回复如token等字段给客户端,这个传参交互的过程需要通过零信任传输,只有https方式可以实现参数透传,其他认证方式无法实现,其他场景如cas账号认证/短信认证/令牌认证/企业微信钉钉验证码认证/密码错误告警等特殊认证需求也可通过https认证实现
4. http(s)场景的落地思路/工作原理/配置详解
4.1. 单独http(s)场景的数据流交互流程如下:
根据工作流得知,零信任服务端和三方认证服务器之间是有数据交互的,此过程由三方认证服务器提供一个api接口,零信任负责把用户端发来的认证数据通过这个接口传给认证服务器,服务器判断是否认证成功再返回结果给零信任,再到用户端
基于以上,API接口的对接调用需要规范标准,需要由认证服务器厂商提供接口文档
接口文档示例如下,需要包含如下几个内容
请求方式(规范传参方式)
请求地址:API接口地址
请求体参数:账号密码等字段的键值格式要求
请求示例:请求报文的格式举例
以零信任视角出发,需要重点关注四个内容:请求方式、请求格式、响应格式、响应参数。
4.1.1. 请求方式:
请求方式决定了控制中心到认证服务器之间http请求的方式,也决定了账号密码等字段传输的格式
请求方式支持两种---Get和Post,两种方式的区别就是标准的http协议的区别
get方式请求没有请求体,只有请求头部,账号密码等字段只能放在头部字段传输
Post方式可以携带请求体,请求体格式多种多样,如表单、混合、json、xml、文本,可以把账号密码等字段放到请求体中传输
基于安全性考虑,一般建议使用post方式,具体原因建议自行学习http原理,本文不做赘述
4.1.2. 请求格式:
结合实际配置介绍请求格式的区别
在认证服务器配置页面可以通过选择请求地址前边GET和POST切换查看,如下图
以GET方式举例,请求中有四个地方需要配置
而POST方式则多出一个请求体
接下来分为两部分介绍请求设置参数
第一部分介绍请求地址、请求头部、请求URL、请求cookie、请求体
第二部分是结合第一部分的内容对自定义请求变量的功能做讲解
4.1.2.1. 请求地址:
认证服务器提供的API接口URL,直接让认证服务器提供即可
4.1.2.2. 请求头部:
用于设置http的请求头部字段,可以自定义键值对,也可以自定义字段然后使用默认自带的值,如时间戳,用户名密码等,但是基于安全考虑不建议把账号密码字段放在请求头/请求URL/cookie中,所以不建议使用GET方式;
典型场景就是在POST类型请求中需要定义请求体的格式,需要把对应格式放在请求头部
举个例子,如果post的请求体的格式是json,则需要在请求头部设置conntent-type,值为application/json,告知服务器端我发送的请求体的格式是json
4.1.2.3. 请求URL参数:
用于设置http请求的URL后边带的后缀,也是根据需求自定义或者调用已有默认参数,在get方式中可用于放置账号密码字段
举个例子:如果认证服务器要求零信任传给认证服务器的账号字段名为”username”,那么在零信任中就需要想办法设置一个名为”username”的字段,然后把账号放置在这个字段值上,再传输给认证服务器
具体配置举例如下图,在请求参数中自定义一个字段”username”,其对应的值设置为”user.username”,”user.username”就是零信任默认保存账号的字段,意思就是当用户输入完账号密码点击认证后,会先把用户输入的账号放在零信任默认存储账号的字段”user.username”,然后再把”user.username”的值放到自定义的字段”username”中,再传输给认证服务器,使认证服务器能够根据自身的规则完成账号密码字段的匹配,其他字段同理
4.1.2.4. 请求cookie:
用于设置cookie参数,如果无此需求或者认证服务器给的接口文档没提到,则可以不设置,留空即可
4.1.2.5. 抓包理解传参流程和字段对应关系
以GET方式举例,预先配置好请求头/URL/cookie参数,部分键值对自定义、部分字段自定义然后值调用默认参数,在atrust认证页面输入账号张三,密码123,点登陆,在认证服务器端抓取来自控制中心的认证报文,内容对应如下,可以看到请求头部/url/cookie在报文中对应的位置,还有自定义键值对和调用默认参数的键值对的信息
以账号字段举例,会显示在URL一行,对应的字段名是自定义的username,而密码则是调用了零信任默认的键值填写上去,对应的键值对为username:{{user.username}}
4.1.2.6. 请求体:
POST请求才有的功能,一般将账号密码等信息放在请求体内,POST方式下请求体支持的内容格式如下,可以通过这几种方式编写请求体内容
请求体使用的格式是根据认证服务器需求决定,因为最终请求体的内容是需要认证服务器解读的,所以只需要遵守认证服务器的格式要求编辑就行
以实际需求举例:当前认证服务器只能通过json格式接收账号密码信息,认证服务器规范的账号字段名为user-name,密码字段名为user-password,那么结合需求,得出的配置如下
对于以上配置的解读为:
最外层的大括号用于规范json格式
第二三行的user-name和user-passowrd都是认证服务器规定的字段名
第二三行大括号的字段是调用零信任默认的账号和密码字段作为自定义字段的值,其中user.username和user.userPassword就是是零信任默认放置账号密码信息的字段,可以从请求头部等界面看到支持的默认值
最后总结请求体工作流如下
4.1.2.7. 自定义请求变量:
自定义请求变量是更深入的功能,需要理解前边的内容才能理解该功能的能力
此功能的作用是:根据自定义需求将客户端发来的信息通过JS代码做转换/处理,形成认证服务器规范的请求参数,提供给请求头部/url参数/cookie/请求体调用
工作流程示意图如下:用户在登录页填写的账号密码等字段值会先到达自定义请求变量模块处理,处理后再提供给请求设置里调用
4.1.2.7.1. 结合实际案例场景讲解
需求背景:零信任控制中心和认证服务器之间使用http方式传参,账号密码在传输过程中都是明文,但是目前也无法改造成https的,基于信息安全考虑,需要确保在零信任和认证服务器传输账号密码的安全性,确保中间人窃取后无法直接看到真实的密码
解决方案:通过零信任对密码字段做加密,使用自定义请求变量模块将密码字段做加密处理,然后传输到认证服务器
具体配置思路:
a. 启用自定义请求变量
通过js代码将零信任默认的userPassword字段的值进行加工修改
如下图示例,系统默认就填写好了一个示例的js代码,意思将userPassword的字段值做md5加密,并赋值给新字段“env.md5Psw”
b. 将JS代码中加密后的密码新字段”env.md5Psw”参数在请求体中调用,赋值给认证服务器要求的的字段”user-password”
c. 抓包检查确认密码字段已经做了md5加密,至此需求实现
4.1.2.7.2. 场景扩展:
Q:如果不想用md5,可不可以换成其他的加密方式?
A:可以,只需把代码第11行的“code_util.md5”中的md5换成对应加密算法即可
Q:如果要做多层加密怎么办?比如先md5加密再sha1加密,代码该怎么写?
A:让研发写或者用GPT写就完事了
以上示例只是为了便于理解功能,不代表产品能力边界,其他特殊需求建议让研发评估是否可行
4.1.3. 响应格式
响应格式就是指服务器在接收到零信任发来的认证信息校验后,回复给零信任报文的格式,零信任支持解析XML和JSON格式(其他格式需单独评估使用响应数据预处理模块解决)
对应到时序图就是第6步认证服务器回复给atrust的报文
4.1.4. 响应参数:
认证服务器回复给零信任报文的报文内容为响应参数,其中需要包含用于判断认证是否通过的字段,或者其他自定义的信息,比如错误信息,错误码等,零信任需要根据回复的参数判断用户是否认证通过,或者透传指定信息到前端
其中细化的几个配置项有:响应参数、认证成功条件、响应数据预处理
如下图
4.1.4.1. 响应参数作用:
将认证服务器返回的字段放置到零信任的已有的固定参数中,用于实现信息返回前端、多步请求场景的后续调用、未导入用户登录组织架构字段提取
以信息返回前端场景举例分为二种场景,一是错误信息返回场景,二是sdk信息透传场景,接下来会对错误信息返回场景做描述,SDK透传场景会放在另一篇文章讲解
4.1.4.1.1. 错误信息返回场景:
零信任默认提供了错误码和错误信息两个字段,这两个字段的信息可以返回到用户登录页显示出来,可以把认证服务器返回的个性化提示信息返回到前端呈现给用户
举个例子:客户想实现当用户登录密码错误时,告知用户联系管理员处理
此需求的实现方式为:让认证服务器进行开发,当校验不通过时以xml或者json格式返回提示信息,告知用户错误代码500,并让其联系管理员李四,然后零信任将此信息解析到错误信息即可
具体配置思路如下,先找认证服务器侧获取认证服务器返回的错误代码和错误信息的字段名,如下图举例,对应的错误代码字段名为”code”,返回信息字段名为”msg”
零信任配置如下图,将认证服务器返回的两个字段分别解析到内置字段
最终实现效果如下图,零信任会把认证服务器回复的错误码和错误信息放置到认证页
4.1.4.1.2. 未导入用户登录组织架构字段提取:
在用户不导入零信任场景会用到该功能,如下图,自定义用户目录中可以配置未导入用户允许登录,根据认证时解析的组织架构和角色信息获取授权和策略
此功能描述所说的认证时解析的就是指http认证(其他比如cas、oauth等也有)中响应参数配置的组织架构和角色(前提是认证服务器会回复对应字段,零信任才可以解析)
配置示例:
在认证服务器具备回复用户组织架构或角色字段的前提下,如下图组织架构字段的键值对是:“zzjg:sangfor/test”
将对应键解析到响应参数即可
这样就可以实现在用户目录未录入用户信息的情况下登录和绑定对应组织架构
4.1.4.2. 认证成功条件:
用于零信任本身判断认证结果是否通过
以某接口文档举例,其中描述了一个名为”code”的字段,用于表示状态码,状态码为200时是认证成功,500是认证失败,通过此信息就可以判断出认证服务器返回的认证结果
将此参数配置到零信任上,配置如下,意思就是只要认证服务器回复的信息中code字段的值是200,就判断认证通过,其中判断条件可以设置成与或非等形式
4.1.4.3. 响应数据预处理:
将认证服务器响应的数据通过js代码做修改,提供给响应参数/认证成功条件调用
工作流逻辑如图
举个例子说明应用场景:
当前客户认证服务器只能以文本形式返回认证结果,但是零信任只能解析XML和JSON格式的数据,则可以通过响应预处理把其他形式的数据修改成json或xml格式
示例:当前认证服务器返回的数据如下
{ "statusCode": 200, "data": { "headers": { "x-powered-by": "Express", "content-type": "text/plain; charset=utf-8", "content-length": "25", "etag": "W/\"19-fS1BRqWGLDnKMLdtuHUJLdd5nA8\"", "date": "Wed, 19 Jun 2024 15:32:25 GMT", "connection": "close" }, "body": "code,200,msg,认证通过" } }
{ "statusCode": 500, "data": { "headers": { "x-powered-by": "Express", "content-type": "text/plain; charset=utf-8", "content-length": "25", "etag": "W/\"19-zWxstyVfXjxdK4W07g7MTh18keE\"", "date": "Wed, 19 Jun 2024 15:34:04 GMT", "connection": "close" }, "body": "code,500,msg,认证失败" } }
标红位置表示认证结果信息,只是把数据排列起来,使用逗号做分割,不是json或xml格式,零信任收到后无法识别,需要通过预处理代码将认证结果信息转换成json格式
下图代码含义:将body字段使用逗号分割,将分割后的第一位的信息赋值给新建字段code,第三位的信息赋值给新建字段msg
使用发送测试检查配置是否可用:认证成功条件要求code为200,测试信息显示回复的信息是非json,但是测试仍然通过,说明预处理代码配置没问题,可以实现非json转json
工作流程示例如下:
4.1.5. 多步请求
典型场景就是令牌认证/企业微信验证码/钉钉验证码场景,但是很惭愧,这个场景没实践过,这里就不多说了
这部分建议通过2022年9月份的破雾计划学习,其中有具体场景的讲解如下链接和图片
https://bbs.sangfor.com.cn/plugin.php?id=sangfor_databases:index&mod=viewdatabase&tid=227005
4.1.6. Cookie代理下发
关于此功能的作用在设备上就有解释:启用后,将会把认证服务器返回的所有Cookie数据进行代理下发到指定的域名中。适用于业务系统需要访问认证服务器返回Cookie的场景,比如客户业务系统需要单点登录的场景。
为了便于理解该功能,以深信服W3门户举例,用户通过oauth方式登录后,使用f12-应用程序-cookie页面中,可以看到有名为token的cookie,对应的domain域名为泛域名.atrust.sangfor.com,这个cookie就是用于单点登录的,作用就是使用浏览器访问.atrust.sangfor.com对应域名下(包括子域名)的网站时,都可以通过此cookie实现单点登录认证(只是举例,深信服w3是使用的oauth而不是https方式)
对应到控制中心配置页面上需要配置的域名,就是指具体需要使用认证服务器回复的cookie的域名,如下图
使用此功能的前提是认证服务器可以回复cookie才行,回复的格式就是正常http响应中的cookie,不能以响应参数类似的形式传输
注意事项:代理下发的cookie的域名,需要保证和零信任的域名为同根域
配置举例:
当前服务器具备cookie回复能力,通过发送测试可以看到服务器有回复set-cookie,其中cookie名为testcookie,值为123456789,domin也就是适用域名为abc.xyz
此时开启“启用cookie代理下发”,将实际需要使用cookie的域名填写进去
然后在用户端进行https认证测试,通过f12可看到零信任代理下发的cookie,domin已经被改成了ldat.xyz。
这里要注意,代理下发的cookie不会携带httponly、secure、max-age等参数,即使认证服务器实际有回复也不会携带,所以需要注意应用场景和能力边界
4.2. 发送测试:
零信任在https配置界面提供了简单的排错功能,可以借助发送测试功能检查请求返回参数格式及验证账号密码,效果如下图