JWT是一种基于令牌的便捷请求认证鉴权方案。用户状态信息存储在token中,由客户端提供,函数(服务端)无需存储,是一种Serverless友好的鉴权方式。函数计算可以通过用户绑定在自定义域名上的Public JWKS实现对到达自定义域名上的请求进行JWT认证。并根据自定义域名上的配置,将claims作为参数转发给函数,函数无需对请求进行鉴权,只需关注业务逻辑即可。
背景信息
简介
JWT(JSON Web Token,RFC7519)是一种基于令牌的便捷请求认证鉴权方案。用户状态信息存储在token
中,由客户端提供,函数(服务端)无需存储,是一种Serverless友好的鉴权方式。函数计算可以通过用户绑定在自定义域名上的Public JWKS实现对到达自定义域名上的请求进行JWT认证。并根据自定义域名上的配置,将claims作为参数转发给函数,函数无需对请求进行鉴权,只需关注业务逻辑即可。如果需要了解JWT的token
认证流程及基础知识,请参见基于JWT的token认证和JWT简介。
JWT认证流程
自定义域名的JWT认证流程同HTTP触发器的JWT认证流程。
上图是函数计算HTTP触发器利用JWT实现认证的整个业务流程时序图(使用非对称加密算法),步骤详细解析如下。
客户端向自定义授权服务发起认证请求,请求中一般会携带终端用户的用户名和密码。
自定义授权服务读取请求中的验证信息(例如用户名、密码等)进行验证,验证通过之后使用私钥生成标准的
token
。自定义授权服务将携带
token
的应答返回给客户端,客户端需要将这个token
缓存到本地。客户端向HTTP触发器发送业务请求,请求中携带
token
。HTTP触发器使用用户设置的公钥对请求中的
token
进行验证。验证通过之后,将请求透传给受保护的函数。
受保护的函数处理业务请求,并进行应答。
HTTP触发器将业务应答返回给客户端。
使用限制
可以使用任何方式来生成和分发JWT,函数计算通过触发器配置的Public JWKS来认证JWT。
支持不含
kid
的JWK。支持为一个触发器配置多个JWK。
支持从
header
、Query
参数(GET)、表单参数(POST)和cookie
中读取Token。支持将
claims
作为header
、Query
参数(GET)、表单参数(POST)和cookie
转发给函数。函数计算支持为一个自定义域名配置一组JWT(JWKS),在JWKS中寻找与token中的kid相同的JWK公钥,并使用这个公钥对token进行签名校验。一个自定义域名的JWKS最多只允许一个JWK的kid不存在或者为空字符串。
目前函数计算的JWT支持如下算法。
签名算法
alg取值
RSASSA-PKCS1-V1_5
RS256,RS384,RS512
RSASSA-PSS
PS256,PS384,PS512
Elliptic Curve (ECDSA)
ES256,ES384,ES512
HMAC
HS256,HS384,HS512
EdDSA
EdDSA
HMAC签名算法为对称加密,安全性相对较低,建议使用安全性更高的非对称加密算法。
使用非对称加密算法时,出于安全考虑,您的JWT中只需要包含公钥信息即可,不建议包含私钥信息。
建议使用HTTPS来对请求中的
token
等敏感信息进行保护,可以有效避免Token泄露。
配置JWT认证
前提条件
操作步骤
登录函数计算控制台,在左侧导航栏,选择 。
在顶部菜单栏,选择地域,然后在域名管理页面,单击目标域名。
单击右上角的编辑,在编辑自定义域名页面,设置以下配置项,然后单击保存。
认证方式选择为JWT 认证。
配置JWKS。
为自定义域名配置JWT鉴权,首先需要提供一个有效的JWKS(JSON Web Key Set)。您可以自行生成JWKS,或者搜索JSON Web Key Generator寻找在线可用的生成工具,例如mkjwk.org。如果您已经有pem格式的密钥,可以借助工具(例如jwx),将其转换为JWKS格式。JWKS示例如下。
本文以使用mkjwk.org工具生成JWKS为例进行介绍。如下图所示,选择Key Use、Algorithm和Show X.509,然后单击Generate生成JWKS。在您的代码中需要使用Private Key(下图中①)签发JWT Token,请妥善保存。您可以复制Public Key(下图中②)中的内容填入到控制台中的JWKS的keys数组中。
本文配置的JWKS示例如下。
{ "keys": [ { "alg": "RS256", "e": "AQAB", "kty": "RSA", "n": "u1LWgoomekdOMfB1lEe96OHehd4XRNCbZRm96RqwOYTTc28Sc_U5wKV2umDzolfoI682ct2BNnRRahYgZPhbOCzHYM6i8sRXjz9Ghx3QHw9zrYACtArwQxrTFiejbfzDPGdPrMQg7T8wjtLtkSyDmCzeXpbIdwmxuLyt_ahLfHelr94kEksMDa42V4Fi5bMW4cCLjlEKzBEHGmFdT8UbLPCvpgsM84JK63e5ifdeI9NdadbC8ZMiR--dFCujT7AgRRyMzxgdn2l-nZJ2ZaYzbLUtAW5_U2kfRVkDNa8d1g__2V5zjU6nfLJ1S2MoXMgRgDPeHpEehZVu2kNaSFvDUQ", "use": "sig" } ] }
配置JWT Token。
选择token所在位置和token的名称。token位置支持Header、Cookie、Query参数(GET)和表单参数(POST)。如果token位置选择为Header,则还需为其指定前缀,函数计算在获取Token时,会删除此前缀。
配置JWT Claim转换。
选择透传给函数的参数所在位置、参数原始名称和参数透传给函数之后的名称。映射参数位置支持Header、Cookie、Query参数(GET)和表单参数(POST)。
结果验证
在调测工具(本文以Postman工具为例)中,根据自定义域名的JWT配置,填写自定义域名、Token等,验证是否可以正常通过自定义域名访问函数。如下图所示。
使用配置JWT认证时生成的Private Key创建JWT Token。
使用Postman工具验证自定义域名是否可以正常访问。
在函数计算控制台左侧导航栏选择 ,在域名管理页面获取自定义域名。
在Postman的Headers配置Token参数信息。本文填写的Token示例如下。
名称
值
说明
Key
Authentication
填写在JWT Token 配置中设置的参数名称。
Value
Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiSm9uIFNub3ciLCJhZG1pbiI6dHJ1ZSwiZXhwIjo0ODI5NTk3NjQxfQ.eRcobbpjAd3OSMxcWbmbicOTLjO2vuLR9F2QZMK4rz1JqfSRHgwQVqNxcfOIO9ckDMNlF_3jtdfCfvXfka-phJZpHmnaQJxmnOA8zA3R4wF4GUQdz5zkt74cK9jLAXpokwrviz2ROehwxTCwa0naRd_N9eFhvTRnP3u7L0xn3ll4iOf8Q4jS0mVLpjyTa5WiBkN5xi9hkFxd__p98Pah_Yf0hVQ2ldGSyTtAMmdM1Bvzad-kdZ_wW0jcctIla9bLnOo-Enr14EsGvziMh_QTZ3HQtJuToSKZ11xkNgaz7an5de6PuF5ISXQzxigpFVIkG765aEDVtEnFkMO0xyPGLg
填写在JWT Token 配置中设置的去除前缀Bearer和上一步生成的JWT Token。Bearer与JWT Token之间要有一个空格。
单击Send,查看返回信息。
nametofunction
为Claim透传给函数后的名称。