修复旧钉钉回调丢失域名会话 (#115)
This commit is contained in:
parent
0743f298a3
commit
cc355b32ce
@ -39,7 +39,7 @@ probe="$(curl -sS -o /dev/null -w '%{http_code} %{redirect_url}' --max-time 15 \
|
||||
"http://$SERVER_IP:8442/auth/dingtalk/callback?state=configuration-probe")"
|
||||
status="${probe%% *}"
|
||||
redirect_url="${probe#* }"
|
||||
expected_redirect="https://caiwu.jiansuntuzhi.cn:8442/auth/login"
|
||||
expected_redirect="https://caiwu.jiansuntuzhi.cn:8442/auth/dingtalk/callback?state=configuration-probe"
|
||||
|
||||
if [ "$status" != "302" ] || [ "$redirect_url" != "$expected_redirect" ]; then
|
||||
install -m 644 "$BACKUP_DIR/caiwuxitong-backend-8442.conf" "$TARGET_CONFIG"
|
||||
|
||||
@ -9,26 +9,15 @@ server {
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
client_max_body_size 12m;
|
||||
|
||||
# Plain HTTP is accepted only for the DingTalk OAuth callback registered
|
||||
# by the enterprise administrator. Laravel must still generate HTTPS
|
||||
# destinations after consuming the callback because every following page
|
||||
# on port 8442 is HTTPS-only.
|
||||
# The legacy registered HTTP callback must reach the browser's canonical
|
||||
# HTTPS origin before Laravel reads its session. Proxying it with a forged
|
||||
# Host loses the domain cookie and defeats browser-bound OAuth state.
|
||||
error_page 497 = @plain_http_request;
|
||||
|
||||
location @plain_http_request {
|
||||
if ($request_uri !~ "^/auth/dingtalk/callback(?:[?]|$)") {
|
||||
return 308 https://caiwu.jiansuntuzhi.cn:8442$request_uri;
|
||||
}
|
||||
|
||||
proxy_pass http://127.0.0.1:18088;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host caiwu.jiansuntuzhi.cn;
|
||||
proxy_set_header X-Forwarded-Host caiwu.jiansuntuzhi.cn;
|
||||
proxy_set_header X-Forwarded-Port 8442;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto https;
|
||||
proxy_read_timeout 30s;
|
||||
add_header Cache-Control "no-store" always;
|
||||
add_header Referrer-Policy "no-referrer" always;
|
||||
return 302 https://caiwu.jiansuntuzhi.cn:8442$request_uri;
|
||||
}
|
||||
|
||||
location / {
|
||||
|
||||
@ -60,4 +60,6 @@
|
||||
- 开发节点通过实际只读入口抽查 3 名有有效钉钉唯一值的财务花名册人员,3 名均被新准入查询识别;不输出人员身份、手机号或原始 HR 行。
|
||||
- 生产节点使用现有只读查询入口读到两个确认的财务根部门,说明该节点可独立访问 HR 来源。本次没有在生产执行开户或写入。
|
||||
- 浏览器检查实际 Blade 渲染的虚构账号页面:桌面和 390px 窄屏首次登录提示、管理员绑定页新说明和开户审计。权限保存与后续工作台跳转通过 HTTP 功能测试验证。
|
||||
- 尚未发布,尚未进行真实钉钉扫码开户验收。
|
||||
- `0743f29` 已发布;生产 3 名花名册有效样本判断通过,原 11 个账号保留,10 个旧 remember 令牌已失效,使用新 session cookie 名隔离旧会话(旧会话文件保留于备份)。
|
||||
- 真实扫码发现钉钉开放平台尚未登记域名回调,且当前平台登录账号没有开发者权限。已恢复旧 IP 回调配置;Nginx 必须先通过 302 跳回 HTTPS 域名,不能将旧 IP 请求伪装成域名请求交给 Laravel,否则无法取得浏览器会话。域名登记后再切换生产回调变量。
|
||||
- 自动开户的真实扫码验收仍在进行,不能用只读样本或登录页跳转代替最终开户证据。
|
||||
|
||||
@ -6,14 +6,16 @@ use Tests\TestCase;
|
||||
|
||||
class DingTalkCallbackNginxTest extends TestCase
|
||||
{
|
||||
public function test_plain_http_is_limited_to_the_registered_dingtalk_callback(): void
|
||||
public function test_plain_http_redirects_to_domain_before_laravel_reads_session(): void
|
||||
{
|
||||
$config = file_get_contents(base_path('deploy/host-nginx-8442-dingtalk.conf'));
|
||||
|
||||
$this->assertStringContainsString('error_page 497 = @plain_http_request;', $config);
|
||||
$this->assertStringContainsString('if ($request_uri !~ "^/auth/dingtalk/callback(?:[?]|$)")', $config);
|
||||
$this->assertStringContainsString('return 302 https://caiwu.jiansuntuzhi.cn:8442$request_uri;', $config);
|
||||
$this->assertStringContainsString('add_header Cache-Control "no-store" always;', $config);
|
||||
$this->assertStringNotContainsString('proxy_set_header Host caiwu.jiansuntuzhi.cn;', $config);
|
||||
$this->assertStringNotContainsString('proxy_set_header X-Forwarded-Proto http;', $config);
|
||||
$this->assertSame(2, substr_count($config, 'proxy_set_header X-Forwarded-Proto https;'));
|
||||
$this->assertSame(1, substr_count($config, 'proxy_set_header X-Forwarded-Proto https;'));
|
||||
$this->assertStringContainsString('return 308 https://caiwu.jiansuntuzhi.cn:8442$request_uri;', $config);
|
||||
$this->assertStringContainsString('ssl_certificate /etc/nginx/caiwu-jiansuntuzhi-fullchain.pem;', $config);
|
||||
$this->assertStringNotContainsString('caiwuxitong-backend.crt', $config);
|
||||
@ -25,7 +27,7 @@ class DingTalkCallbackNginxTest extends TestCase
|
||||
|
||||
$this->assertStringContainsString('nginx -t', $script);
|
||||
$this->assertStringContainsString('the previous configuration was restored', $script);
|
||||
$this->assertStringContainsString("expected_redirect=\"https://caiwu.jiansuntuzhi.cn:8442/auth/login\"", $script);
|
||||
$this->assertStringContainsString("expected_redirect=\"https://caiwu.jiansuntuzhi.cn:8442/auth/dingtalk/callback?state=configuration-probe\"", $script);
|
||||
$this->assertStringContainsString("[ \"\$status\" != \"302\" ] || [ \"\$redirect_url\" != \"\$expected_redirect\" ]", $script);
|
||||
$this->assertStringContainsString('DINGTALK_HTTP_CALLBACK_READY=', $script);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user