使用Laravel为Singpass生成Client Assertion时JWT声明校验失败问题
Singpass client_assertion生成报错解决方案
- 检查JWT头部是否缺失
kid字段:Singpass要求JWT头部必须携带kid参数,取值为你在Singpass开发者控制台上传公钥时生成的密钥ID,当前你使用的Lcobucci驱动默认不会自动添加该字段,需要手动配置头部参数。 - 确认
aud声明取值正确:staging环境的audience应为https://stg-id.singpass.gov.sg,需和你请求的授权接口域名完全匹配,不能有多余的路径或拼写错误。 - 补充必填的
jti声明:Singpass要求所有断言必须携带唯一的jti(JWT ID)字段,取值为长度不小于16位的随机字符串,单次请求有效不可重复使用。 - 校验密钥格式有效性:确认你使用的ES256密钥是符合P-256标准的椭圆曲线密钥,私钥文件没有多余的换行、空格或格式错误,公钥已正确上传到Singpass控制台且状态为生效。
- 检查时间戳偏差:确认服务器时间已和NTP服务同步,避免
iat、exp的时间和Singpass服务器时间偏差超过5分钟导致校验失败。
修正后的代码参考:
$jwt = new Lcobucci(new Builder(), new Parser(), '', 'ES256', [ 'private' => 'file://' . base_path('keys/private.pem'), 'public' => 'file://' . base_path('keys/public.pem') ]); // 生成符合要求的唯一jti $jti = bin2hex(random_bytes(16)); return $jwt->encode( // JWT负载声明 [ 'sub' => "******LESBX********ifeGBAU******", 'aud' => "https://stg-id.singpass.gov.sg", 'iss' => "******LESBX********ifeGBAU******", 'iat' => now()->timestamp, 'exp' => now()->addMinute()->timestamp, 'jti' => $jti ], // JWT头部添加kid参数,替换为你自己的公钥对应密钥ID [ 'kid' => '替换为你的实际kid值' ] );
内容的提问来源于stack exchange,提问作者Mudit Gulgulia
相关产品推荐
相关产品推荐

